<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" 
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    <title>Joshua Ayson - Essays</title>
    <link>https://joshuaayson.com/explore/essays/</link>
    <description>Essays from Joshua Ayson&apos;s blog</description>
    <language>en-us</language>
    <lastBuildDate>Mon, 10 Aug 2026 02:57:53 GMT</lastBuildDate>
    <atom:link href="https://joshuaayson.com/rss/essays.xml" rel="self" type="application/rss+xml"/>
    <generator>Astro</generator>
    <copyright>Copyright 2026 Joshua Ayson</copyright>
        <item>
      <title>Hello, Again</title>
      <link>https://joshuaayson.com/2026/07/25/hello-again/</link>
      <description>Three weeks ago I wrote about a script called hello, the one warm door into my system. I kept pulling the thread and the door turned out to be the outermost loop, the one that asks whether the whole thing can still become useful. This is what I found standing behind a greeting: cybernetics, nested watchers, and the rule that intelligence never gets its own hands.</description>
      <content:encoded><![CDATA[Three weeks ago I wrote about [a script called hello](/2026/07/03/hello/). One word typed in the morning, and the day opens: the system greets me, tells me where I am, and unfolds the rest. I ended that essay saying I was still figuring out what the next program is. This week the answer got written down, not as code but as a decision record, the same way I log any architecture choice that matters. Its title: hello v2, the warm door becomes the outer control plane. The next program is a promotion for the first one.

Here is the question that cracked it open. On a Mac there is a built-in supervisor called launchd. It is the thing that starts programs on a schedule and restarts them when they die, and it is what starts hello in the first place. So launchd sits on top, right? It runs the show, and hello is just one of the programs it runs.

No. And the reason it is no turned out to be the most useful idea I have picked up all month. The thing that starts a program is not the thing that owns its purpose. Your alarm clock starts your morning. It does not run your life. Execution order and authority are two different ladders, and they can point in opposite directions. launchd starts hello, but the policy lives in hello, the picture of what the whole system is supposed to be able to do. The supervisor is an actuator, a switch on a timer. The greeting is the governor.

Once I saw that, the whole stack rearranged itself into [a set of nested loops](/2026/07/15/the-loop-was-the-top-of-a-stack/), each one watching the layer below it from outside. At home the loops are still modest, a handful of scheduled jobs that rebuild my notes into dashboards and push a morning brief, all of them started by that same supervisor on a timer. But the next tenant of the laboratory is already picked out, and studying it is what forced the issue. Kubernetes, if you have not met it, is software that keeps other software to its promises. You declare what should be running and it ceaselessly compares reality against the declaration and repairs the difference. It is a beautiful machine and it has one blind spot: it cannot restart itself. If the cluster is down, no amount of cleverness inside the cluster can help, because the cleverness is down too. Something outside has to notice. And something outside that. Every watcher has to live outside the failure boundary of the thing it watches, all the way up, until you reach the outermost watcher, the one that asks the only question that matters: can this whole system still become useful from where it stands right now?

That question is hello's job. That is the promotion.

The promotion comes with a rule about restraint: delegate to the smallest competent controller. Every layer gets its own question and nothing reaches past its own. Kubernetes asks whether the running workloads match the declared ones; a missing pod is its problem and nobody else's. The workflow engine asks whether a requested process completed. The agents ask what a piece of evidence means. hello asks only the outermost question, whether the whole system can still fulfill its purpose, and when the answer is no it does not climb down the stack to fix a pod. It restarts the ground the lower loops stand on and lets each of them do its own job on the way back up. I own the remaining category: anything with a red gate on it waits for me.

None of this is my invention. There is a field that named all of it in the 1940s: cybernetics, from the Greek word for steersman, the study of how systems steer themselves with feedback. The thermostat that reads the room and nudges the furnace. The governor on a steam engine, two spinning weights that throttle the valve before the machine tears itself apart. IBM named the ambition again in 2001, autonomic computing, systems that configure, heal, and tune themselves the way your nervous system runs your heartbeat without consulting you. I want that property with one amendment, and the amendment has become the whole project: the adaptation has to stay legible. A system that quietly heals itself is a system whose story I can no longer read, and an illegible system is the thing this entire practice exists to prevent. I keep rediscovering these fields by need, building some contraption in the dark and then finding out it has had a name for eighty years. I have stopped being embarrassed by that and started reading. Rediscovery is how I learn that the canon is real.

The other field standing behind the door is what the old AI researchers called cognitive architecture, the study of how a mind might be organized as separate organs. One memory for what happened. Another for how things relate. A narrow working attention. A reasoning organ. What struck me, sketching my own small version, a local model waiting on the laptop, the databases still on the bench, is where the intelligence turned out to live. Not in the model. The model is one organ, the interpreting one, and it is the easiest part to swap out. The intelligence, if that word applies at all, lives in the organization: in what gets remembered, what gets connected, what gets checked, and what is allowed to happen next. I have now built or sketched this same organism four separate times, in four different rooms, and it keeps coming back with the same organs. A shape that keeps re-deriving itself has stopped being a project and started being an anatomy.

In my system the model never gets its own hands. It can read, and it can propose, and its proposals have to come from a short fixed list, the way a chess piece can only make its legal moves. Something dumber and more trustworthy than the model carries the proposal out, a human signs off where judgment is required, and every action has to declare its expected outcome before it runs and come back afterward and show it. A green checkmark proves nothing. A process can be running and still be useless, the way a phone can be on and nobody home. The only proof of life I accept anymore is [a completed loop](/2026/07/14/a-loop-is-seven-things/): a question went in, an answer came out, the answer was written down, and the writing was read back. Automation without that verification step is just faith with better logging.

The small local model gets even less authority than the big ones. Its job title in the design is sensor, not judge. It may classify, tag, extract, and summarize, and every answer it gives has to validate against a schema or fail loudly and get escalated, because a guess must never silently become the record. What it lacks in judgment it repays in coverage: local tokens cost nothing, so the sensor can afford to read everything, every night. At the sensing tier, coverage beats intelligence. The weak check says the model process is running. The strong check says a prompt went in and a valid structured answer came back out. The whole design is built from that one substitution, a capability tested where a component used to be trusted.

One more thing about the decision record, the part I trust most: it ends with a prohibition. The design is accepted, the schemas are named, and nothing gets built before August 1. There is [an exam on the 31st](/2026/07/19/same-score-half-the-time/) that owns the runway, and the standing trap of this whole practice is perfecting instruments instead of using them. So the promotion sits on paper for now, where it can be reviewed and argued with, and the door itself has not changed at all.

So hello still says hello. The greeting has not changed and I will not let it change; the warmth was always the point. What changed is what stands behind the word. Some days it is confusing to live inside a system while building it, the builder and the resident answering the same door, and some days it all runs together into more than one head wants to manage. Most days it is the most fun I have ever had as an engineer. The first program anyone writes is the machine greeting the world. The second one, for me, was my system greeting me. The third is turning out to be the system learning to answer the greeting truthfully. Hello. Are you there? Are you able? Show me the loop.]]></content:encoded>
      <pubDate>Sun, 26 Jul 2026 04:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/07/25/hello-again/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/07/hello-again.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>Same Score, Half the Time</title>
      <link>https://joshuaayson.com/2026/07/19/same-score-half-the-time/</link>
      <description>I failed another practice exam today. Same score as my best one, and my best is still a fail. But I finished in half the time and it felt easy in a way it never has, and I think the number is the last thing that moves, not the first.</description>
      <content:encoded><![CDATA[I failed another practice exam today.

Forty out of sixty-five. That's 61 percent, and the real exam wants roughly 72. My whole record is three timed sets: a 55 on May 10, my first time out; a 61 on May 24, on a different set; and today's 61, a retake of the same set that gave me the 55. Today ties my best score, and my best score is still a fail. The ceiling has read 61 twice now. I booked the actual test for the morning of July 31, twelve days from now, so the timing wasn't lost on me.

But the score doesn't show the clock. The set gives you two hours and ten minutes. I used one hour and six. Last time I needed nearly all of it and came out with my head buzzing. This time I moved through the questions the way you move through a neighborhood you've started to live in, and when I hit submit I wasn't tired.

Same number, half the time, none of the strain.

## The number moves last

I run, slowly, a couple of miles at lunch when I can. Anyone who runs knows the thing where your pace doesn't improve for weeks and then you notice your heart isn't pounding at that pace anymore. The stopwatch says nothing changed. Your body knows everything changed. The stopwatch is a lagging indicator. The heart rate is a leading one. Fitness shows up in effort first and in time second.

I think learning works the same way, and I think this is easy to forget when a deadline is staring at you. The score is the stopwatch. What moved today was the effort: questions that used to require me to reconstruct [half of Amazon's cloud](/2026/06/15/aws-is-smaller-than-it-looks/) from first principles now read like sentences I could just answer. The recall got fast and cheap. The subscores moved too: the cost domain, a flat zero on that first May set, came in at a third today. What's left isn't a fog anymore, it's a list. Twenty-five specific things I didn't know.

There's a mechanical reason the number sits still, too, and it helped to spell it out for myself tonight. A score is a threshold laid over the whole exam. Every question I almost know still grades as a zero, and the almosts show up nowhere on the report. Understanding can climb for weeks while the number holds flat, because the number only moves when enough almosts flip all the way over to yes. The learning is continuous and the score is a step function, and a step function spends most of its life looking flat.

And a list of specific things you don't know is the single best input a study system can receive.

## The misses become cards

The system I study with is built around exactly this. Every miss from today went through a small pipeline and came out the other side as flashcards, fourteen new ones, in a spaced repetition deck. Spaced repetition is the flashcard method that shows you a card again right before you would have forgotten it, so every review arrives right where it does the most good. The practice exam's job is not to grade me. Its job is to find the gaps and feed them to the deck, and the fourteen newest cards in it are today's twenty-five misses, distilled.

Tonight, before bed, I ran it: seventy-five cards, forty-nine right, 65 percent. Nearly the exam's number again, which makes sense, since they're measuring the same holes. The difference is what happens next. The exam prints the score and walks away. The deck takes each card I missed and schedules it to come back right before I'd forget it again.

So [the loop](/2026/07/14/a-loop-is-seven-things/) is closed. Read, test, harvest the misses, drill the cards, test again. Seven practice sets left in the bank, twelve days, one set every other day. The plan doesn't change because a number stayed flat. The plan was never about the number.

## Writing the pressure down

The tie stung, and twelve days doesn't feel like plenty. I wrote the pressure down in my journal tonight the same way I'm writing it here, because pressure that stays in your head steers the car, and pressure that gets written down just rides along.

Pass or fail, I'll report back on August 1. My money says the score moves last, and then all at once.]]></content:encoded>
      <pubDate>Mon, 20 Jul 2026 01:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/07/19/same-score-half-the-time/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/07/same-score-half-the-time.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>Knowing Isn&apos;t a System</title>
      <link>https://joshuaayson.com/2026/07/17/knowing-isnt-a-system/</link>
      <description>I bought the IPO everyone wanted, and a quiet part of me narrated the mistake while I made it. The post-mortem found the real bug: a category I had built so I could skip my own system. Knowing isn&apos;t a system.</description>
      <content:encoded><![CDATA[There's a specific kind of mistake I want to talk about, because I made it in the open, to myself, in real time.

Last year there was an IPO everyone wanted, a company selling its shares to the public for the first time, the one you would have heard of even if you never follow markets. I bought it. Not because my system told me to; my system had nothing to say about a brand-new listing with no history to model. I bought it because I wanted to own a piece of the story. And when it dropped, I bought more. I laddered down into a position the plan never asked for, at prices the plan would have said no to, and the whole time a quiet part of me narrated the mistake as I made it.

That's the part I keep turning over. Not that I lost money. Losing money is tuition, and I've paid it before. It's that I wasn't fooled. I had the information. I knew the trade was bad while I was making it, and I made it anyway.

For a while I filed that under willpower. I should have been more disciplined. Next time I'll just not. But "just don't" has never once worked, for me or for anyone, on anything that actually matters. Willpower is the tool you reach for in the exact moment it's weakest. Asking it to save you mid-impulse is like asking someone mid-fall to decide not to.

So I did the thing I do with every other part of my life I can't trust in the moment. I wrote it down and took it apart.

Engineers have a name for this: a root-cause analysis. A post-mortem, but for a decision instead of an outage. You keep asking why, not to punish yourself but to walk backward from the symptom to the thing underneath it. Why did I buy it? Because it was going up and I felt left out. Why did that beat the plan? Because the position was never in the plan; it lived in a blind spot, a "conviction" bucket with no rules attached. Why was there a bucket with no rules? Because I'd told myself conviction was different, that some things you buy with belief instead of process. Which is the exact sentence every bad trade wears as a costume.

The root cause wasn't the IPO. It was a category I had built specifically so I could skip my own system. I'd left myself a legal way to do the wrong thing.

The fix wasn't to feel worse about it. The fix was to give the position a job. Instead of holding it and hoping, I put a simple, boring, rule-based process on top of it, the same one I keep in [a little black book](/2026/07/02/the-little-black-book-of-hansuru/): get paid a little to wait, with the exit price decided in advance, before any feeling gets a vote. It doesn't erase the loss. It turns a frozen mistake into something that moves, a position with a plan at last, even if the plan showed up a month late and poorer for it.

This reaches past trading, and it's the same thing I keep finding everywhere I look. A system is not for your best self. Your best self doesn't need one. A system is what you build for the version of you that won't listen: the tired one, the greedy one, the one who wants to own the story. You don't out-discipline that person. You build a track where the right move is the easy move, and the wrong move requires a decision, said out loud, that you'd be a little embarrassed to make. That is the whole reason I'm building [an operating system for my own judgment](/2026/06/25/complexence-os/): structure that holds when the person holding it doesn't.

I'm early at this. I'm not writing from a mountaintop. I'm writing from the part of the climb where you can still see your own footprints going the wrong way. But that's the point. The footprints are the material. The catch isn't never making the mistake. The catch is having somewhere for the mistake to go, a place that turns "I knew and did it anyway" into a rule that makes next time a little harder to get wrong.

Knowing isn't a system. Knowing is the easy part. The system is what you build for the moment knowing isn't enough.]]></content:encoded>
      <pubDate>Fri, 17 Jul 2026 20:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/07/17/knowing-isnt-a-system/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/07/knowing-isnt-a-system.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>The Loop Was the Top of a Stack</title>
      <link>https://joshuaayson.com/2026/07/15/the-loop-was-the-top-of-a-stack/</link>
      <description>I typed my thirty-two loops, then drew them as a graph, and thought the loop was the top of the system. It turned out to be the roof of a stack eight floors deep, and the floor holding all the weight is the smallest one: the edge.</description>
      <content:encoded><![CDATA[Two essays ago I [typed the thirty-two jobs](/2026/07/14/a-loop-is-seven-things/) that run underneath my days and found the word loop had been hiding seven kinds of thing. One essay ago I [drew those jobs as a graph](/2026/07/14/the-view-youre-missing-is-the-graph/) and found the pile I had feared was a short chain with one load-bearing root. I thought that was the bottom of it. I thought the loop was the top of the system, the thing everything else served.

The loop is the top. It is just the top of a stack, and I had never counted the floors below it. When I did there were eight, and the one bearing all the weight was the smallest, and the one I had paid the least attention to: the edge.

## The floor is the edge

For a year I built my system the way most people build anything they are trying to understand. I catalogued the things. Every job got a name, a type, a criticality, a place in a registry, and the registry grew more complete every week and [no more legible](/2026/07/14/the-view-youre-missing-is-the-graph/). What I did not see until I went looking for the floor is that a catalogue of things, however complete, is an inventory, and an inventory is the least intelligent structure you can build. It can tell you what you own. It cannot tell you what any of it is for.

The thing that tells you what a job is for was never in the job. It was in the line running out of it to another job. My registry had those lines all along, sitting in two plain fields on every entry: what this job reads, and what this job writes. I had been reading them as attributes of the node. They are not attributes of anything. Reads-what-that-one-writes is a relationship, and a relationship is its own object, with its own existence, independent of the two things it joins.

Call that object the edge, and the whole picture inverts. The node stops being the unit of the system and becomes a place where edges meet. A goal that requires a capability, a task that advances a goal, a decision that was based on a piece of evidence, an event that changed a state: in every one of those the node is a noun you could have guessed and the edge is the sentence that carries the meaning. A system built around its nodes accumulates into an inventory. A system built around its edges becomes something you can reason about, because reasoning is almost entirely a matter of relationships, and the edge is where a relationship finally gets to be a first-class thing instead of a footnote on a node. This is the same inversion I make with any territory I try to [chart](/domain-cartography/). The things were never the map. The lines between them were.

## Three floors of meaning

An edge tells you two things are related. It does not tell you what the relation means, whether it is still true, or what it might cause. Those are three separate questions, and the stack answers them on three separate floors, which is the part I would have collapsed into one if I had built it carelessly.

The first floor is knowledge, and its whole job is to refuse to treat unlike claims as alike. A deployment failed is a fact. The deployment failed because of configuration drift is a claim. The configuration might be generated nondeterministically is a hypothesis. Freeze deployments until we know is a decision. The failure went away after the rollback is an observation. Those five sentences are about the same night, and a careless system files them as five equal truths and moves on. They are not equal. A system that files them as equal knows nothing; it only stores strings. A fact and a hypothesis have different rights: one you build on, the other you test, and a structure that cannot tell them apart will eventually act on a guess as though it were the ground.

The second floor is time. My first instinct with any piece of state was to keep it current. This project is healthy, and when it stops being healthy, overwrite healthy with at risk. That instinct quietly destroys the most useful thing the system could have known. The moment you overwrite the old value you can no longer ask when it changed, or what was decided while the old value was still believed, or how long this had been drifting before anyone noticed. So the temporal floor keeps the transitions instead of the latest value. Healthy from the first to the twelfth. Degraded from the twelfth to the fourteenth. At risk since. Now the state is not a fact, it is a history, and a history answers questions a snapshot cannot: what changed, when the slipping started, which assumptions have quietly expired. A system without this floor is a dashboard. A system with it has a memory.

The third floor is cause, and it has to be built to stay humble. It is tempting to write message overload causes lost focus as though it were a law. It is not a law, it is a guess with a number on it, and the causal floor makes the guess wear its status on its face: message overload possibly contributes to lost focus, confidence of sixty-eight percent, here is the evidence, here is the counterevidence, status still open. Once a cause is provisional in that way, an intervention stops being a fix and becomes an experiment. Put a twice-daily wall around the messages. Predict that the context switching drops. Measure the switches. Watch the number move or fail to move, and let the result raise or lower the confidence on the edge. That is what turns a diagram of your intuitions into a model that updates when the world disagrees with it.

## The floor where it finally moves

Everything so far is understanding, and understanding does not do anything. At some point the system has to act, and action cannot happen in a graph, because a graph is allowed to contain cycles and action is not. Research informs a build, the build produces observations, the observations revise the research: a perfectly good cycle to understand, and an impossible one to execute, because you cannot do the first thing until you have done the last. So the execution floor does something specific with the graph above it. It projects a path through it. It takes the goals that are actually live and the evidence that is actually current, and it flattens that into a directed acyclic graph, an ordering with no cycles, a thing you can walk from front to back. The discipline that governs orderings like this is a solved one, which I found out the [slightly embarrassing way](/2026/07/14/you-reinvented-data-engineering/).

This is the sharpest line in the whole stack, and I had it backward for a long time. The graph is supposed to hold the complexity. The DAG is not supposed to hold any of it. The DAG is a single actionable slice pulled out of the graph for right now, and when now changes you pull a new one. I used to keep an eternal task list and try to make it match reality, which is exactly the wrong shape, because a list that never regenerates rots the moment the world moves. When I drew my own jobs as a graph, fourteen of the thirty-two lay in a real dependency spine and eighteen depended on nothing at all, and the head of that spine was a single job that [builds the store](/2026/07/14/one-writer-per-artifact/) almost everything else reads. That spine is the DAG the graph was carrying inside it. The other eighteen are free and can run in any order, and the whole point of keeping the two floors separate is that I can see at a glance which is which. The graph is where the complexity lives. The DAG is the one clean path I pull out of it when it is time to move.

## The two floors that keep it alive

Everything under here is inert. It is a very good map, and a map does not update itself. The seventh floor is the one that does, and it is where the system stops being a data model and starts being something closer to an attention. Give the map five verbs and it comes alive. It senses what changed. It orients that change against the goals and risks already in the graph. It proposes options and the next path to walk. It acts, through me and through the agents I trust. And then it learns, by comparing what it expected against what actually happened and revising the edges accordingly. That last verb is the one most systems skip, and skipping it is what turns a living thing back into a filing cabinet. A confidence that never moves after the evidence arrives is not a belief. It is a decoration.

In practice this floor has a shape I have come to rely on. It runs on its own, does the sensing and the orienting and the proposing without me, and surfaces only the things that need a human: the broken edge, the goal that nothing is moving toward, the task moving toward no goal, the assumption that has gone stale. I review the exceptions, not the roster. That inversion, from watching everything to being shown only what changed and matters, is the whole return on building the floor, and it is the most direct thing I have built toward [the objective function](/2026/07/08/engineering-orientation/) I keep coming back to: improve my orientation while reducing what it costs me to stay oriented.

Then the eighth floor, the one I mistook for the whole building. The loop is not another structure. It stores nothing the floors below it do not already store. It is the thing that keeps running, the pass that goes sense, orient, frame, model, decide, compose, act, observe, revise, and return to the top with attention pointed at whatever now deserves it. People compare this to the OODA loop and it is close, but OODA was built for a fighter pilot who has no time to update a causal model mid-turn. This loop has the time, because most of what I am trying to stay inside does not move at the speed of a dogfight. It moves at the speed of a quarter, a codebase, a body, a business, and the slower speed is exactly what makes the revision step both affordable and necessary. The loop is real. It was just never the foundation. It is the roof, and it only stands because there are eight floors under it holding it up.

## The rule the whole stack exists to protect

If I had to throw away everything in the stack but one rule I would keep this one, because every other floor is quietly built to enforce it. There are three structures in the building that must never collapse into each other. There is the graph of what appears to be related out in the world. There is the graph of what the system currently believes those relations mean. And there is the single path it has decided to act on next. World, belief, action.

Almost every system that fails at this fails the same way. It lets them touch. It treats what it retrieved as true, then treats what is true as what it intends, then treats what it intends as permission to move. Each of those little promotions feels like efficiency, and each one is where the accident comes from. The stack refuses all three. A relationship that shows up in the world does not get to become a belief on its own. A belief does not get to become an action on its own. Something has to carry it across each gap on purpose, with the evidence attached, and where it matters with my hand on it.

That gap is where governance lives, and it is why I keep building this instead of buying a tool that would move faster by skipping it. The whole point of [standing inside something complex without coming apart](/complexence/) is that you get to keep what is out there, what you think it means, and what you are about to do about it as three separate things. Every floor of the stack is in service of holding those three apart long enough to choose. This is also the clearest example I have of why I think complexity is a thing to [make visible](/making-complexity-visible/) rather than a thing to reduce: I did not simplify the system, I gave it floors, and the floors are what let me see it.

I started by typing my loops and thinking the loop was the top of the system. It is the top. The system is taller than I knew. It goes all the way down to a single relationship between two things, and every floor in between exists so that a relationship never turns into an action without someone deciding it should.]]></content:encoded>
      <pubDate>Wed, 15 Jul 2026 16:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/07/15/the-loop-was-the-top-of-a-stack/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/07/the-loop-was-the-top-of-a-stack.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>One Writer Per Artifact</title>
      <link>https://joshuaayson.com/2026/07/14/one-writer-per-artifact/</link>
      <description>Typing my automation handed me most of its rules for free; the type carries the contract. One rule came free with nothing, and it was the one my system was breaking: every file gets exactly one job that writes it. On the difference between rules you remember and rules the structure carries.</description>
      <content:encoded><![CDATA[There is a directory in my automation that took me longer to understand than any code I have ever written, and it contained no code. It was a data directory, the one my dashboard reads from, and the reason it resisted understanding was simple to state once I finally saw it: more than a dozen different jobs wrote into it. To answer the smallest possible question about that folder, what is in here and can I trust it, I had to hold every one of those writers in my head at once, know their schedules, and reason about who wrote last and what they overwrote. One folder, a dozen-plus owners, which is to say no owner at all. That directory was the soup at the center of my system, and it was soup for one nameable reason. It violated a rule I did not know existed.

The rule is: every artifact gets exactly one writer. One file, one job responsible for it, no exceptions you did not choose on purpose.

## Rules that come free, and the one that does not

I found the rule while [typing my loops](/2026/07/14/a-loop-is-seven-things/), and the typing is what makes its absence visible. Most of the rules a pipeline needs turn out to ride along with the type, free, the way grammar rides along with a part of speech. Call a loop an emit, meaning it pushes out into the world, and its contract arrives with the word: safe to run twice, because someday the scheduler hiccups and it runs twice, and an emit that double-fires is an incident. Call a loop a report and the opposite contract arrives: pure snapshot, no side effects, regenerate it a hundred times for free. Call a loop a watch and the strictest clause of all shows up: it reads state and returns verdicts and must never, ever write data, because a watcher that writes has become part of the watched. Call it an ingest and it inherits the duty to survive its source being down. I did not compose any of that. The types carry it, and every future loop I write will inherit its contract at the moment of naming.

Single writer per artifact is different, and the difference is why it is the rule that actually gets broken. It is not a fact about any one loop. It is a fact about the space between loops. Nothing in a transform's own contract prevents a second transform, written eight months later on a busy day, from writing to the same file. Each loop is individually correct. The collision lives in the pair, and no one is standing where the pair is visible. That is precisely how my soup directory happened. Not one bad decision. A dozen individually fine decisions, each one adding a writer, no vantage point from which the accumulation could be seen. Fog never announces itself. It accrues.

## Chosen twice, or drifted into

The rule is not "two writers must never happen." I have one deliberate violation: a job that seeds a file and a second job that fills in the rest, colliding by design, and the design is written down where the next reader will find it. That violation is fine, and the reason it is fine is the distinction the whole rule turns on. A violation you chose and documented is a design decision, visible, priced, revisitable. A violation you drifted into is fog with a commit history. The rule's real text is not "one writer, always." It is "never two writers *by accident*." Constraints in a system you build alone are not there to stop a rogue teammate. They are there to stop the accumulation of reasonable Tuesdays.

I did not invent the rule, and finding its provenance was [the same relief as finding the rest of the discipline](/2026/07/14/you-reinvented-data-engineering/). In data engineering it is close to load-bearing doctrine, and one tool, Dagster, is built around it wholesale: its core unit is the asset, an artifact with exactly one producing job and its lineage tracked for free. I studied Dagster and did not adopt it; at my scale the machinery costs more than it returns. But the idea rode home free. Think in artifacts with single owners, enforce it by hand, and you have taken the tool's best thought without taking on its care and feeding.

## Rules you remember, rules the structure carries

A rule I have to remember is a rule I will eventually break. Not through carelessness, through arithmetic: I hold a rule in attention a hundred times and lapse once, and the system keeps the lapse. Every rule stored in my memory decays at the rate of my worst day. This is the same reason I [build maps outside my head](/complexence/) instead of trusting recall, and it took me embarrassingly long to see that it applies to laws as much as to maps. Memory is the wrong substrate for anything that has to hold.

A rule the structure carries does not decay. When the contract rides on the type, and the type is declared in a registry, and a check reads the registry, the rule outlives my attention to it. The next loop I add, months from now, in a hurry, gets named, and the name hands it its obligations, and a violation surfaces as a red line in a report instead of as a mystery in a folder. The system has begun to govern loops that do not exist yet. That is the property that separates a system from a pile. A pile is ruled by the memory of whoever built it and degrades as the memory does. A system carries its own law.

So the arc closes, and it was one move all along, run three times at three depths. [Typing the loops](/2026/07/14/a-loop-is-seven-things/) made each one legible. [Drawing the graph](/2026/07/14/the-view-youre-missing-is-the-graph/) made the whole visible. Writing the contracts into the structure made the whole durable, so the legibility survives me getting busy, which is the only condition under which legibility is ever actually tested. None of it required a rewrite, a platform, or a better memory. It required names, a drawing, and a place outside my head for the rules to live. The territory did not change. It was charted, and now the chart enforces itself.]]></content:encoded>
      <pubDate>Tue, 14 Jul 2026 22:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/07/14/one-writer-per-artifact/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/07/one-writer-per-artifact.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>The View You&apos;re Missing Is the Graph</title>
      <link>https://joshuaayson.com/2026/07/14/the-view-youre-missing-is-the-graph/</link>
      <description>I gave every job in my automation a receipt, a health check, and a green light, and the system still would not fit in my head. A dashboard shows the state of the parts. The question I actually had was about the shape of the whole, and no amount of state answers a question about shape.</description>
      <content:encoded><![CDATA[I built the dashboard I thought I wanted, and it did not fix the thing that was actually wrong.

The dashboard was the reasonable move and I do not regret it. My automation had been invisible, so I made it visible: every job got a receipt when it ran, a health check, a staleness clock, and a place on a board that shows the whole roster at once, green for fine, red for failed, amber for stale. It caught real failures I would have found days later or never. A board that goes green when the night's work finished is worth having, and I recommend building one.

But visible turned out not to be the same thing as legible, and the gap between those two words is this entire essay. With the board glowing green in front of me, I still could not answer the questions that actually mattered. If this job dies tonight, what goes quietly stale downstream of it? Which of these thirty-two rows is load-bearing and which are decoration? What has to run before what? The board had the state of every part and nothing whatsoever about the shape of the whole, and every question I cared about was a question about shape. By then I had [typed the loops](/2026/07/14/a-loop-is-seven-things/), so each one was legible alone. The whole stayed dark.

That is not a flaw in my dashboard. It is a flaw in dashboards. A list answers "what is the condition of each thing," and it answers well. It is structurally silent on "how do these things hang together," because the answer to that is not stored in any row. It lives between the rows, in the relationships, and a list throws the relationships away at the door.

## Same data, different projection

Here is what finally worked, and the modest size of the change is the lesson I keep relearning. I added no data. No new instrumentation, no new collection, nothing measured that was not already measured. Each job in my registry already declared two plain facts about itself: what it reads, and what it writes. I had been rendering those facts as text in a table. I started rendering them as arrows instead. A job is a node. "This job reads what that job writes" is an edge. Same registry, same facts, different projection.

The picture that came back reorganized my understanding of a system I had personally written every line of. The jobs fell into columns nobody designed: sources on the left producing raw material, then the derivers that shape it, then the composers that assemble the shaped pieces, then, at the far right, the deliverers that push the finished thing out to where I actually see it. Left to right, the data moving the way water moves. I had built a watershed one creek at a time and never once seen the river system.

And across the top, the graph stated its one-line verdict on a year of my low-grade dread: thirty-two loops, fourteen in the dependency spine, eighteen with no internal dependencies at all. A short critical chain, not a tangle.

![The Loop DAG panel from my ops dashboard: thirty-two loops in four columns, sources, derive, compose, deliver, with red arrows tracing the critical path out of the context store, dashed lines for the round-trips through Apple, and a row of eighteen independent loops along the bottom.](/images/essays/2026/07/the-view-youre-missing-is-the-graph-loop-dag.webp)

*The actual panel. Left to right: sources, derive, compose, deliver, the water flowing the way water flows. Every red arrow is the critical path, and every red arrow traces back to the context store at the top left. The dashed lines are the dependencies that share no file. The bottom row is the eighteen loops that depend on nothing, listed flat because flat is what independence looks like.*

I had been carrying the tangle version in my head the whole time. That is what an unseen system does: it gets imagined, and the imagination always draws the worst case, because a pile you cannot see is a pile you cannot bound. The truth was that more than half my loops depend on nothing and can run in any order, and the part with real structure is fourteen jobs in a chain short enough to trace with a finger. The relief was not that the system turned out simple. It is that the system turned out *knowable*, and the dread had been a rendering problem, not an engineering problem.

## What the graph knows that the board cannot say

One node sat at the head of the chain, drawn in red because everything on the critical path descends from it: the job that builds the context store nearly everything else reads. I wrote that job on some ordinary day to solve some ordinary problem, and it has since become the root of the whole system, a promotion nobody announced, least of all to me. On the dashboard it is one green row among thirty-two green rows, visually identical to jobs that matter a hundred times less. On the graph it is unmistakably the keystone.

Which exposes the quiet failure a dashboard cannot even represent: every light green, and the system wrong anyway. If that root job silently produces stale output, every downstream job runs happily on old data, each one succeeds, each one stamps its receipt, and the board shows a wall of green describing a system that is confidently out of date. State is fine. Shape is broken. No row can say so, because the brokenness is not *in* any row. Now that I can see the root, I know exactly which single job to guard hardest, and I learned it from a picture instead of from an outage, which is the cheapest tuition there is.

Then there were the dashed arrows, and these are the part I would keep if I had to give the rest back. Most edges in the graph are ordinary: one job reads a file another job wrote. But four of them are drawn dashed because no shared file exists. They round-trip through the outside world. One job pushes an event out to my calendar; hours later a different job pulls the calendar back in, event included. Push, then pull, through Apple's servers in the middle. No common artifact, no visible connection, nothing on any list that would ever associate those two jobs. And the ordering between them is absolutely load-bearing: run the pull before the push and it quietly reads yesterday, misses today, and reports success. Nothing errors. Nothing goes red. A dependency that exists in no artifact, only in the shape of the system, is a dependency exactly one kind of view can show you, and it is not the kind with rows.

## Orientation, not data

There is a question I have started asking of every surface I build, and it is the question this whole experience taught me to ask: does this improve my orientation while reducing the effort it costs to stay oriented? I wrote about that question [as an objective function](/2026/07/08/engineering-orientation/), and the dashboard and the graph split cleanly across it. The dashboard improved my orientation and charged me for it, because turning thirty-two rows into a mental model of the system is work, performed by me, again, on every glance. The graph did the work once, in the rendering. The shape arrives through my eyes instead of being reconstructed behind them. That is the difference between a view that contains the answer and a view that contains the ingredients of the answer, and I had spent a year paying the assembly cost without noticing it was on the bill.

More data was never the missing thing. Nobody drowning in a system they cannot see needs another metric. The missing thing was a projection, the one that matches the question. State questions want lists. Shape questions want graphs, and nearly every question that decides whether a system is understandable, what depends on what, what is load-bearing, what breaks first, is a shape question wearing work clothes.

I keep arriving at this same move from different directions. A month ago I [built the link graph of this blog](/2026/06/12/i-mapped-my-own-blog/) and found the site's real structure was not the one I imagined; its [atlas](/atlas/) is on the wall now. This time the territory was the machine that runs my days. Both times, [the charting move](/domain-cartography/) was identical and the yield was identical: the pile became a place. That is what I mean when I say [complexity should be made visible](/making-complexity-visible/) rather than reduced, and the loops taught me the precise version of it. The list told me what was running. The graph told me where I stand. Those are different products, and only one of them was ever going to lift the fog.]]></content:encoded>
      <pubDate>Tue, 14 Jul 2026 20:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/07/14/the-view-youre-missing-is-the-graph/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/07/the-view-youre-missing-is-the-graph.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>You Reinvented Data Engineering</title>
      <link>https://joshuaayson.com/2026/07/14/you-reinvented-data-engineering/</link>
      <description>The best thing anyone told me about my own system this year was that I had not invented it. The scripts I grew by hand are a data pipeline, the shape is a DAG, and the discipline is solved. What the tools actually sell, why I am not buying yet, and the difference between wanting an engine and wanting a map.</description>
      <content:encoded><![CDATA[The best thing anyone told me about my own system this year was that I had not invented it.

For months I had been treating my automation as a private, shapeless thing, a system with no architecture and no best practices because I had made it up as I went. Thirty-two jobs, grown one at a time, each solving whatever that day's problem was, none of them designed against a plan because there was no plan, only a series of Tuesdays. It felt like mine in the way a mess feels like yours. Then I sorted the jobs by what they do to data, [seven clean types fell out](/2026/07/14/a-loop-is-seven-things/), and the thing that surfaced next should have been deflating. This is a solved discipline. It has a name, a body of practice, and a shelf of tools, and I had walked the whole road without noticing it was paved.

The field is data engineering. The business of moving data from where it is produced to where it is used, transforming it on the way, keeping the pipes from clogging. That is not a metaphor for what I built. It is what I built, poorly, alone, without the words. Even the shape has a name. When jobs feed each other, output becoming input, and nothing circles back on itself, you have a directed acyclic graph. A DAG. Pull the world in, transform in stages, push the results out, watchers off to the side reporting on the health of the whole. Every serious pipeline on earth is a version of that picture, and so was mine, drawn on no wall, living only in the order my scripts happened to run.

## Uncharted usually means unnamed

My instinct the whole time had been that I was in territory with no map. That instinct was wrong in a specific and common way: I mistook unnamed for uncharted. The territory was thoroughly charted. I had simply never looked up the chart, because I did not know my situation was an instance of anything, because the thing you build yourself never announces its own category. It just accretes, Tuesday by Tuesday, until it feels too particular to be anyone else's problem.

Finding the name changed the whole posture of the work. A mess you believe is unique is a mess you defend alone. A pattern with a name comes with lineage, prior art, a vocabulary for the exact failure you are living through, and other people's decade of mistakes already paid for. I did not lose anything when I learned my system was ordinary. I gained the entire field that had been standing behind it, and the fog I had blamed on the system turned out to be, one more time, a fact about words. You cannot navigate by a chart you have refused to look up, even when you are the one who built the territory it describes.

## What the tools are actually selling

The shelf of tools came with the name. Airflow, Dagster, dbt, each built to govern graphs of exactly my shape. So the question arrived on schedule: do I adopt one, or keep hand-rolling? There are two easy answers. Professionals use Airflow, so use Airflow. You are one person, keep it simple. Both skip the reasoning, and the reasoning is where the useful part lives.

Every one of these tools is a frozen answer to somebody else's scale, the same way [every AWS service is a frozen answer to a distributed-systems trade-off](/2026/06/15/aws-is-smaller-than-it-looks/). Read what the tool assumes and you can read the problems its makers had. Airflow assumes hundreds of tasks, teams of operators, backfills over years of history, service-level agreements with consequences. To hold all that it brings a scheduler, a metadata database, a web server, and a fleet of workers. At thirty-two jobs on a personal machine, that is a second system larger than the first, adopted to govern it. dbt assumes the wrong world entirely: SQL transforms over a data warehouse, when mine are files over a repository. Adopting it would mean reshaping the problem to flatter the tool.

Dagster assumes something more interesting, and it earned real study before I set it down. Its unit is not a task but an asset: a specific artifact with exactly one job responsible for producing it, lineage between artifacts tracked for free. That idea is not machinery. It is a way of seeing, and it sees precisely the thing my system got wrong, the directory that a dozen jobs all wrote into so that nobody owned it. So I took the idea and left the installation. Think in artifacts with single owners. Enforce it by hand. If I ever do adopt the tool, the system will already be shaped the way it expects, and the migration will cost nearly nothing. Borrowing the concept and skipping the machinery is not a consolation prize. Most of what a mature tool knows is in its concepts, and the concepts are free.

## An engine, or a map

Underneath the tool question there was a sharper question, and answering it is what actually settled the matter. What did I want?

I thought I wanted orchestration. I did not. My loops already run; the operating system's own scheduler fires them and has never been the problem. What I wanted was to *see* the system. Which loop feeds which. What everything depends on. Where the load-bearing pieces are. That is not an engine. That is a map, and I already held every fact the map needed, sitting in a registry I maintain anyway, waiting to be drawn instead of listed. The drawing took an afternoon. No daemon, no database, nothing new that can break at three in the morning.

That is the oldest rule I trust, the one that has survived every domain I have carried it into: the gains are in subtraction, and the fastest way to make a small system fragile is to bolt a large one onto it for problems it does not have. An orchestrator in my basement would not be sophistication. It would be a new tenant, eating maintenance attention forever, hired for a job that does not exist here yet.

The word that matters is yet, and a yet without a tripwire is just a mood. So I wrote the tripwires down. The day I am doing backfills by hand and hating it. The day I catch myself reinventing retries and alerting instead of configuring them once. The day a second machine or another person needs this on a shared clock. Any one of those, and the answer flips, and the tool earns its weight, and I will adopt it without ceremony because the decision was already made and dated. Until then the engine stays on the shelf.

The map came off the shelf immediately, and what it showed me, [the actual graph of my own system](/2026/07/14/the-view-youre-missing-is-the-graph/), is the next essay: the view that turned thirty-two things I maintained into one system I could finally stand inside and read.]]></content:encoded>
      <pubDate>Tue, 14 Jul 2026 18:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/07/14/you-reinvented-data-engineering/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/07/you-reinvented-data-engineering.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>A Loop Is Seven Things</title>
      <link>https://joshuaayson.com/2026/07/14/a-loop-is-seven-things/</link>
      <description>Thirty-two automated jobs run underneath my days, I wrote every one of them, and I could not hold the system in my head. The problem was never my memory. It was a word. &quot;Loop&quot; was one word doing the work of seven.</description>
      <content:encoded><![CDATA[Thirty-two automated jobs run underneath my days. They pull my calendar into a repository, watch my money, build my dashboards, mirror my notes to my phone, and I wrote every one of them, one at a time, each on the day I needed it. In theory nobody on earth understands this system better than I do. In practice I could not hold it in my head. I would sit down to reason about the whole and it would slide out of focus, and the more of it I built, the worse the sliding got.

I kept blaming my memory. The problem was a word.

I called all of them loops. The job that pulls the calendar in, a loop. The job that reads a folder and writes a summary, a loop. The job that pushes a file back out to a surface I look at, the job that checks whether the sync is healthy, the job that carries data between two machines, the job whose entire purpose is to run the other jobs in order. Loop, loop, loop. And a single word is a promise that the things underneath it are the same kind of thing. These were not. I was holding one category that was secretly seven, with no name for any of the seven. That is not a memory problem. That is fog, and it was being manufactured at the vocabulary layer, upstream of anything my memory could do about it.

## The seven

The sorting took one question. Not what is this loop, which invites a story, but what does this loop do to data, which forces an answer. Asked that way, thirty-two jobs fell into seven kinds, cleanly, with almost no argument at the edges.

**Ingest** pulls the world into the repository. Calendar, reminders, the things that live out there and have to come in. The world is not always reachable, so an ingest loop has one governing fact of life: its source will be down someday, and it has to shrug rather than crash.

**Transform** takes data already in the repository and makes more data in the repository. Read a folder, extract, derive, assemble. Nothing enters, nothing leaves. Fourteen of my thirty-two are transforms, which surprised me. Most of the system is the system talking to itself.

**Emit** pushes the repository back out into the world. A file becomes a calendar event, a mirror on another machine, something that shows up somewhere without my hands on it. An emit writes to the world, so it has to be safe to run twice, because someday it will run twice.

**Report** writes a snapshot for me to read. A status page, a summary, the thing I open with coffee. For months I filed these as emits, and the split turned out to matter more than any other line I drew. A report has no blast radius. Nothing leaves the machine, nothing downstream fires, and I can regenerate it a hundred times at no cost. Emit and report look identical from a distance. One can hurt me and one cannot, and a typology that cannot tell those apart is not finished.

**Watch** reads the state of the system and returns a verdict. Is the sync healthy. Is the money system green or red. Not data, judgment. And the sharpest rule in the whole grammar belongs here: a watch must never write data. The moment a watcher starts producing data it stops being the thing that tells me the truth and becomes one more thing I need the truth about.

**Transport** moves data between machines. Two of these. No transformation, no opinion, just carrying.

**Orchestrate** fires the others in the right order. There is exactly one, and its product is not data at all. Its product is sequence.

Ingest, transform, emit, report, watch, transport, orchestrate. The whole zoo, and not one loop among the thirty-two needed a story to place it.

## Why the fog lifted

A word as vague as "loop" cannot carry rules. It told me nothing about how any job was allowed to behave, so there were no rules, so every job was a special case I had to remember individually, and thirty-two special cases is past what I can remember. That was the fog. Not too many things. Too many things with no grammar.

A type carries rules the way "loop" never could. Say "this is an emit" and idempotence arrives with the word. Say "this is a watch" and never-writes-data arrives with the word. I did not get better at remembering my system. I stopped needing to remember it, because the knowledge moved out of my memory and into the vocabulary, and vocabulary does not get tired. The full set of contracts, and [the one rule no type hands you for free](/2026/07/14/one-writer-per-artifact/), grew into its own essay.

The types also caught a second overloaded word, and this one stung, because I had built it myself. Each loop carried a field called its tier, and the tiers had never cohered no matter how I rearranged them. Typing the loops showed me why. Some tier values described what a loop was for. Others described how much it hurts when the loop fails. Two different questions, one slot. It was "loop" all over again, a single word quietly doing the work of two, and the repair was the same repair. Split the axes. What it does. How loudly it fails. What clock it runs on. Whether it is a loop I drive or a loop that drives me, because biology and money-weather run on their own schedules and I only get to observe and align. Four plain fields, and a frustration I had carried for months dissolved without any code changing at all.

Naming is not the paperwork you do after the thinking. Naming is the thinking. Both times, the confusion was never in the loops. It was in the words I had draped over them.

## What the types were waiting to show me

Typing each loop made it legible alone. It did not show me the shape of all of them together, and the shape is where [the real payoff was waiting](/2026/07/14/the-view-youre-missing-is-the-graph/): drawn as a graph, the pile I had feared as a tangle turned out to be a short critical chain with one load-bearing root, which is a different essay. It also turned out that none of this territory was uncharted, that I had [reinvented a known discipline by hand](/2026/07/14/you-reinvented-data-engineering/), and that the discovery was a relief rather than an embarrassment. That is a different essay too. And all of it, the types and the graph and the contracts, turned out to be a few floors of [one stack that runs down to a single edge](/2026/07/15/the-loop-was-the-top-of-a-stack/), which is the essay to read last.

What belongs here is the part I keep turning over. The seven types were not imposed. They were extracted. They had been in the loops the whole time, latent in what each script actually did, and sorting by behavior did not create the typology, it uncovered one that was already true. That is the same move I make when I [map any domain](/domain-cartography/): go into a territory that will not resolve, find the structure that was already there under the noise, and draw it. The only difference is where the territory was. This time it was my own machine, built by my own hands, and it still needed charting, which tells you something about how little "I built it" has to do with "I can see it."

So now I have a diagnostic I expect to use for the rest of my life. When a pile of things you understand individually refuses to cohere as a whole, stop studying the things. Go find the word that is secretly plural. The fog is almost never in the system. It is in a name, holding seven kinds of thing in one syllable, waiting for you to ask what each one actually does.]]></content:encoded>
      <pubDate>Tue, 14 Jul 2026 16:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/07/14/a-loop-is-seven-things/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/07/a-loop-is-seven-things.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>Finding Edgar Morin</title>
      <link>https://joshuaayson.com/2026/07/12/finding-edgar-morin/</link>
      <description>Edgar Morin died in May at 104, and I met him through his obituary. He spent eighty years on the question I have been building around: how to think inside the weave without cutting it apart. Two book reviews are coming. This is the marker I am leaving at the trailhead first.</description>
      <content:encoded><![CDATA[Edgar Morin died in Paris on May 29th. He was 104. I met him through his obituary, which is a strange direction to meet someone from: the life already complete, compressed to a page, and the page reading like it was addressed to me.

He spent most of a century on one problem. Knowledge got carved into disciplines, each one clean inside its own walls, and the carving made us better at parts and worse at wholes. His answer was what he called complex thought, pensée complexe. Not complexity as a pile of complications. Complexity as the weave: the loops where causes become effects and come back around as causes, the opposites that stay opposed and still need each other, the whole that lives inside its parts while the parts keep remaking the whole. Reduction asks what it can remove until a thing becomes manageable. Morin asked what has to stay connected for the thing to stay true.

I read that and sat still for a minute.

There is a question I thought belonged to me: how does a person stay oriented inside systems too large to hold in one head? I called the capability [Complexence](/2026/06/17/complexence/) and started building [the machine to run it](/2026/06/25/complexence-os/). Maps instead of answers. Judgment kept for the human, structure handed to the machine. And here is a man born in 1921 who worked the same mountain for eighty years from the other face. He worked it as epistemology, as the question of how thought itself must change. I am working it as operations, as the question of what you actually build so a person can act inside the weave without coming apart. He is not a predecessor I can claim, only one I can study.

So I ordered the books. *Homeland Earth* is on my desk, barely started. *On Complexity* is in the mail. This is not a review of either one; I have read maybe twenty pages. This is the marker you leave at a trailhead so you can remember what you believed before the walk changed you. The reviews will come here when I have earned an opinion.

## Opposite shores

Then I read about his family, and the thing turned personal.

Morin was born Edgar Nahoum. His family were Sephardic Jews from Salonica, the city now called Thessaloniki in Greece. Sephardic comes from Sefarad, the old Hebrew name for Spain. When Spain expelled its Jews in 1492 the families scattered east across the Mediterranean, and Salonica became one of the great cities of that scattering. Four centuries later the Nahoums moved again, Salonica to Marseille to Paris, where Edgar was born. He wrote a whole book about it, *Vidal and His Family*, his father's life told as the history of a people carried inside one household.

My own inheritance is split between two worlds: German genes on one side, Puerto Rican on the other. And the Puerto Rican half is itself a weave of three strands: African, Taíno, the Indigenous people of the island, and Spanish, the strand that traces back to Iberia. That is exactly what you would expect and proves nothing specific: Spain moved west across the Atlantic starting in 1493, and Puerto Rico is one of the places where that movement became a people, made of exactly those strands. I cannot name the town the Spanish strand left or the year the boat sailed, and the trace is likely many centuries deep by now. I do not need any of that for the shape to be visible.

Two lines out of the same peninsula. His went east through the Mediterranean, through expulsion and empire and Salonica. Mine went west through the Atlantic, through colonization and mixture and an island. Five hundred years later one line produced a philosopher of complexity in Paris, and the other produced me in Nevada, at a desk with a laptop and the same question in my chest. Morin and I may stand on opposite shores of the same Iberian dispersal, his line moving east through the Mediterranean, mine west through Puerto Rico, each arriving generations later at the problem of how fragments remain one.

It is not a blood claim. Ideas do not ride in DNA, and I have no genealogy connecting a Nahoum to anyone in my line. It is a pattern, and I am a person who notices patterns, and part of the discipline is saying out loud which patterns are evidence and which are just beautiful. This one is just beautiful. That is allowed.

## Marseille

Get a map of the Mediterranean and put your finger on Marseille. 43.2965 north, 5.3698 east.

The city is 2,600 years old and it has never been finished. Greeks founded it, Romans took it, and everyone since has passed through: Jews, Occitans, Catalans, Italians, North Africans, Spanish traders. A port is a strange kind of place. It is a boundary that only works by being crossed. It stays itself by taking in what is not itself. Marseille sits roughly between the Spain my line left and the Salonica his family left, and his family passed through it on the way to Paris, and when I look at the map my eye keeps returning there like a tongue to a loose tooth.

Morin had a name for why. His hologram principle says the whole is written inside the part: a person carries a civilization the way a drop of seawater carries the ocean's chemistry. A port city carries the whole sea.

If someone in Marseille ever reads this page, that would please me out of all proportion to sense. The essay would have crossed back over its own subject.

## The name

I had to decide what to call him in this post, so here is the story of the name.

Edgar Nahoum became Edgar Morin in the French Resistance. At a meeting of resistance fighters in Toulouse he introduced himself by the cover name Manin, after a character of Malraux's. His comrades misheard it as Morin, and the misheard name stuck, and he wore it for the next eighty years. A name he took on in danger, layered over the name Sefarad gave his family. Nahoum underneath, Morin on top, both true. He of all people would refuse to pick one.

So: Morin, because it is the name he made. Nahoum, once, because it is the name that carries the story. That is how I will write him.

## Before the walk

Morin loved a line from the Spanish poet Antonio Machado: traveler, there is no path; the path is made by walking.

Here is my walking plan, stated now so I cannot pretend later that I never had one. I will read *Homeland Earth* as his planetary proposal, the argument that Earth itself is now the homeland and no local home makes sense apart from it. I will read *On Complexity* for the method. Each one gets its own review here when I finish it. And while I read, I will test his principles against the system I am building, one at a time, and write down where they hold and where they break.

I expect to find that ideas I thought were mine have older names. Good. That is the point of reading the dead.

He died six weeks before I found him. I missed him by that much, after 104 years. So this is the only greeting available:

Bless you, Edgar Nahoum Morin. Thank you for leaving the path unfinished. I am starting to walk it.]]></content:encoded>
      <pubDate>Sun, 12 Jul 2026 19:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/07/12/finding-edgar-morin/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/07/finding-edgar-morin.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>Engineering Orientation</title>
      <link>https://joshuaayson.com/2026/07/08/engineering-orientation/</link>
      <description>Making complexity visible is the method. Orientation is the objective function. The research program now has an installable runtime, laboratories that keep their data, and its first pre-registered experiment, running on my own life.</description>
      <content:encoded><![CDATA[Ten days ago I published [the science of complexence](/2026/06/28/science-of-complexence/) with a promise attached: I would work on it out loud. This is the first field report, and it starts with a correction to my own mission statement.

I have been calling the work *Making Complexity Visible* for a year. I still am. It is the right name for the mission and I am not softening it. But a long conversation kept pointing one level beneath it, and what is underneath is sharper. Visibility is a method. The objective is orientation.

## The objective function

A mission gives you a direction. It does not tell you whether any given step helped. "Make the system legible" sounds like a goal, but nobody ever wanted a map. People want to know where they are, what matters, what changes next, and what they can do about it. The map is instrumental. Orientation is terminal.

So the precise question, the one every dashboard and agent and diagram and daily brief now has to answer, is this:

> Does this thing improve a person's orientation while reducing their cognitive effort?

You can ask that of a trading dashboard, a release pipeline, a journaling practice, a codebase map, and a language-learning routine, and it is the same question every time. That is what makes it an objective function instead of a slogan. Complexity becomes visible so that orientation improves. Visibility that does not buy orientation is decoration.

The reframe also forced an admission. The mission statement has a measurable core, and measurable things can fail. Which is the point. A research program that cannot fail is a brand.

## The operating system move

The correction exposed a structural problem. Complexence, as shipped, was something you read and then applied by hand. Every place I actually use it, my repositories, my daily practice, my projects, was generating observations and small results, and none of that could flow back into the science without dragging private life into a public repo.

The fix is the oldest pattern in systems design. Linux never contains your documents. Git never contains your business. Terraform does not know your architecture. Each provides a language, your world runs on top of it, and the language never learns what your world is.

Complexence is now that shape. The [public repository](https://github.com/OrganicArtsLLC/complexence) holds grammar, never knowledge: definitions, operators, role contracts, schemas, install tooling. Any project can install a thin scaffold and become a **laboratory**: it runs the roles, tracks its own experiments, logs its own measurements, and keeps every bit of its data. The only thing that ever travels back to the public repo is an abstraction, a pattern stripped of every domain noun, and it moves only after it has shown up in at least three different contexts.

The discipline compresses to one line, and it is the load-bearing line of the architecture: labs are consumers of Complexence. They are not Complexence.

I will not tell you what my labs are. That is the point of the design. What I can tell you is that the public repo now opens with a research index, every open question carrying an ID you can cite, so an experiment in a private lab can say precisely which public claim it feeds without saying anything else at all.

## The measure, and what it is not

An objective function needs an instrument. This is where the most caution is required, because the failure mode of frameworks like this one is a formula that describes everything and predicts nothing.

The candidate measure is called legibility, written Λ. The shape of it: a map of a system is worth what it provides in compression, prediction, and actionability, divided by what it introduces in distortion and costs in cognitive load. A system becomes legible when the ratio clears one, when the map gives more usable orientation than it costs or distorts. A bad map makes complexity simpler but false. A good map makes it simpler and more actionable. The mission restated with a threshold in it: making complexity visible means increasing Λ.

As written, Λ is a picture of a trade-off, not a computation. The five factors live on no common scale, and they are not independent, compress harder and you distort more. What survives scrutiny today is smaller: hold the system fixed, compare two maps, and ask which one raises the ratio. That is an ordinal judgment. The cardinal number does not exist yet. Two of the five factors, how well the map predicts the system and what the map costs to use, can be grounded now, and their ratio is the defensible core.

So Λ ships in the spec labeled as what it is: a candidate, a comparison scaffold, with its debts listed beside it. It becomes a real measure when a laboratory shows a Λ proxy tracking a real outcome. The theory already predicted this would be the hard part. Measurability is the whole bet.

## The first laboratory is my life

The pilot lab is the one where I am both operator and subject, and its first experiment points at the instrument itself.

Before any claim about measuring orientation, there is a prior question. Will the measurement happen at all? So experiment one is fourteen days of a single evening habit: one table row per day, did orientation go up or down, roughly why, on a scale that fits in a glance. The prediction is pre-registered, written down before a single row exists. If I fill the log at least ten days out of fourteen, and the scores agree with a blind re-reading of my own journal at least four times out of five, the instrument survives. If not, the instrument is too heavy, and that is the finding. It generalizes: a measurement scaffold that a motivated person will not fill in on his own life will not be filled in anywhere.

Either way there is a result. The first one closes around July 21 and will be written up here whichever direction it points. The prior two experiments in this program came back null and invalid, and both write-ups are public, sitting in the repo next to the hope. The next one gets the same treatment, whatever it says.

## Out loud includes the mistakes

One more thing happened on day one, and it belongs in the report.

Within an hour of shipping the privacy boundary, I violated it by accident. A push carried old local history that still held a few private breadcrumbs, names of things I work on that have no business in a public repo. The guardrails written that same week contained their own remedy, and it ran: the history was rewritten clean within minutes, and the checker that guards every future commit now knows those words and refuses them. The boundary held because the rule existed before it was needed, and the rule did not care how I felt about force-pushing.

That is the thesis in miniature. Systems outside your head, carrying the discipline your head will drop under load.

## Lab notes

Every experiment that closes gets written up here, in a running series I am calling lab notes. Null results, invalid runs, instruments too heavy to use, and the occasional thing that works. Each note names the public research question it feeds, so the essays and the repository stay projections of one idea instead of drifting apart. The theory has a law about that drift, and I no longer get to ignore it.

A theory that never touches an instrument stays a philosophy. The first instrument is already running.

## More on the idea underneath

- [Complexence](/complexence/), the capability all of this serves.
- [Complexence OS](/2026/06/25/complexence-os/), the daily method the labs install.
- [The Science of Complexence](/2026/06/28/science-of-complexence/), the formal program these measurements feed.
- [The open repository](https://github.com/OrganicArtsLLC/complexence), where the runtime, the research index, and the results live, including the failed ones.]]></content:encoded>
      <pubDate>Wed, 08 Jul 2026 16:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/07/08/engineering-orientation/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      
    </item>
    <item>
      <title>Hello</title>
      <link>https://joshuaayson.com/2026/07/03/hello/</link>
      <description>The first program you write used to be the machine greeting the world. Hello, world. I built a different first program: my own system greeting me. One warm door instead of four scattered starters, and the greeting sits inside the loop it opens, so it can reach in and improve itself.</description>
      <content:encoded><![CDATA[For years the first program anyone writes prints two words to a screen. Hello, world. You type it, you run it, and the machine says hello to the room it just woke up in. It is a small thing and it is a real thing. The machine announces that it is on, that the wiring holds, that something can now happen. I wrote it once like everyone does, and I have written a version of it in every language I have touched since.

Lately I have been building a different first program. Not the machine greeting the world. My system greeting me.

I did not plan it that way. What I had was a mess of starters. One script to build the context store and run the pipeline. Another to bring the dashboard up. A third to check the health of the whole thing. A command in a separate tool to open the day's log. Each one worked. None of them was the door. I would sit down in the morning and have to remember which lever to pull first, and in what order, and the remembering was its own small tax before any work began. So I tried to collapse them into one. I called the first attempt boot.sh, because that is what it did, it booted the machine. It ran fine and I hated it. Boot is what you do to a server. It is cold. It has nothing to say to the person sitting in the chair.

I sat with that for a while. Then the name came. hello.

Not hello world. Just hello. I type hello and the day opens. The context store rebuilds, the dashboard comes up, the log for today is waiting, and the system says good morning back to me and tells me where I am. What decan we are in. What is on the calendar. What I left unfinished yesterday. One word in, and instead of me pulling four levers in the dark, the whole loop unfolds through a single warm door.

The difference between boot and hello is the difference between two disciplines. Boot belongs to software engineering, where you are building a thing for a machine to run and a world to use. hello belongs to what I have started calling cognitive engineering, where the thing you are building is the loop you think inside, and you are building it together with a machine that thinks back. In the first, the program greets the world. In the second, the program greets you. The world does not need to be woken up. I do.

I know how close that sounds to a gimmick, a cute rename over the same shell script. I do not think it is. The name changed how I use the thing. When the entry point is a greeting, sitting down feels like being met instead of being put to work. That is not decoration. It is the whole point of building your own operating loop by hand, so that the first contact of the day is warm and yours, and not a wall of tasks shouting for attention.

hello is inside the loop it opens. When something is off in how my mornings go, I do not go hunting through four scripts. I open the one door and I fix the door. The greeting improves itself. It is seen across every system I run, so a change I make there shows up everywhere downstream. You greet the system and the system greets you back, and both of you get a little better at the greeting each time. A loop that can reach in and improve the loop is the thing I have been chasing under every name I have given this work. I keep returning to it because it is the real shape of the whole practice, the same [complexence](/complexence/) thread I have been pulling for months, the loop that folds back on itself and tightens.

None of this is finished. hello does less than I want it to. It does not yet know when I am running on no sleep and should be handed less, not more. It does not read the room the way a person greeting you would. Right now it is a warm door and a status line, and the warmth is real but the intelligence behind it is thin. I want the greeting to eventually know me well enough to change what it says based on who is sitting down that morning. That is a long way off and I am fine with it. The direction is right and the door is open.

What I keep coming back to, sitting there in the morning with one word typed and the day unfolding in front of me, is how much I love this. Building the loop I think inside. Working with a machine that meets me halfway and builds it with me. Cognitive engineering, if that is what it is. The first program used to be the machine saying hello to the world. Mine is my system saying hello to me. I am still figuring out what [the next one](/2026/07/25/hello-again/) is.]]></content:encoded>
      <pubDate>Fri, 03 Jul 2026 18:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/07/03/hello/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/07/hello-the-door.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>The Little Black Book of Hansuru</title>
      <link>https://joshuaayson.com/2026/07/02/the-little-black-book-of-hansuru/</link>
      <description>A book I wrote about selling options for income, built on one law: survive first. It shows a record most books would hide, and that is the reason it exists. Out now in Kindle and paperback.</description>
      <content:encoded><![CDATA[I wrote a book about money, which is not a thing I ever expected to do, because for most of my life money was the one subject I kept at arm's length. I knew my numbers cold. Income, expenses, every account and what was in each one. Past that I had buy and hold and a tidy-up once in a while, and no map at all.

Last October I read Taleb's *Antifragile*, and because I work in finance I could not read it as just a book. It was describing the ground I stand on all day. I came out of it wanting a hard domain to point my mapping at, and options was the one I chose. I loved the corner I walked into. Not the lottery-ticket side everyone talks about, the buying. The slow institutional side, the selling, where you collect a small steady payment for carrying someone else's risk and most days nothing happens and you keep it. It fit around the rest of a life. It did not ask me to watch a screen all day.

I did not find this corner alone. A friend, Michael Cecere, pushed me down the road that led here, first into agent-mode coding, then toward pointing it at markets, crypto before options. The book carries his name in the dedication for it.

The name is 反する. Said out loud, it is *hansuru*. It means to go against. There is a second meaning riding the same sound, half, never all in. So the whole name is one instruction. Go against the crowd, and never bet everything. That is the book in two characters.

The first move I ever made was the hedge. Before I sold a single option for income I bought protection for the day the bottom falls out, because that day was the one I actually feared. I have been through the bad stretches, more than a few, and every time all I could do was watch it happen and wait for it to pass. Something changed when the protection was on. A crash stopped being only a thing that happens to me. It became a time to act, another position, a part of the plan. When the market is up I have a move, when it chops along I have a move, and when the bottom falls out, for the first time in my life, I have a move there too. That is the feeling that started all of this.

As I write this, the working layer of [the system](/hansuru/) has not yet net made money.

The income collected steadily for six calm months, and then one volatile month took it back and more. That is the exact failure mode the book spends chapters warning about, and I lived straight into it, on my own account, with my own money. That month I won two trades out of fourteen. I could have waited until the ledger turned green and written the book from the far side of a win. Most people do. But a record with no losing stretch is a sales page, and I did not want to write a sales page. I wanted to write the true thing.

The structure held. The Foundation, the boring safe majority I never touch, never flinched. Zero never got close. The account kept trading the next month. What the system has proven so far is that it survives. What it has not yet proven, on my own account, is that it pays. I am telling you that on purpose, because the reasons I still run it are the actual argument of the book.

I did not set out to write about trading. I set out to build a system and [map a hard domain](/how-to-map-a-domain/) until it made sense, which is what I actually do, lately with AI in agent mode, the same build-and-map practice I run on a production system at work. I wrote everything down the whole way. Every trade, every reason, the feeling underneath the reason, what the news was doing and what the account held after taxes. The book grew out of the writing. The constant was never the strategy. It was the loop. Build, watch what happens, map it, adjust, watch again.

I am not telling anyone to trade options. I would not advise anyone into it. A small slip can cost real money and a real mistake can be devastating, and I mean that the plain way. Careful is not a nice-to-have here. Careful is the rule. The book is education and research, not advice. I share my own method and my own bruises ([one of the bruises got its own post-mortem](/2026/07/17/knowing-isnt-a-system/)), and what you do with your money is yours.

If you have never traded an option in your life, the appendices build the instrument up from nothing, from a butcher's counter, with a first move sized so it cannot hurt you. If you already sell premium, the frame is the part I think is worth your time. The four jobs a book of trades has to do. The five regimes. Sizing that keeps a bad day from being the end. The hedge that bleeds all year on purpose and is supposed to.

This one is close to me. It came out of a real year, with real losses in it, and it says so on the first page. The bruises are the part I trust most.

*The Little Black Book of Hansuru* is out now, [on Kindle](https://www.amazon.com/dp/B0H7FL9484?tag=organicartsll-20) and in [paperback](https://www.amazon.com/dp/B0H7FRDPCK?tag=organicartsll-20). There is more at [hansuru.com](https://hansuru.com), including my ongoing trade journal, kept in percentages.

反する.

*This post contains affiliate links. If you purchase through these links, I may earn a small commission at no extra cost to you. Thank you for supporting this blog.*]]></content:encoded>
      <pubDate>Thu, 02 Jul 2026 16:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/07/02/the-little-black-book-of-hansuru/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/07/the-little-black-book-of-hansuru-hero.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>The Science of Complexence</title>
      <link>https://joshuaayson.com/2026/06/28/science-of-complexence/</link>
      <description>I built a method, pointed it at my own thirty-four repositories, and watched the sprawl become a page I could read. Then I tried to prove its deeper claim and the first experiment came back null. Under the practice is a field: the science of complexence, the loop as a recursive equation, meaning velocity, and the cognitive form, an idea held apart from how you say it. A research program, published openly, nulls and all.</description>
      <content:encoded><![CDATA[A week ago I gave a name to something a person does. The capability of standing inside a system larger than yourself and not coming apart. I called it [complexence](/2026/06/17/complexence/), a human quality, the way we say competence or presence.

Then I used it on the messiest thing I own. I have thirty-four code repositories, most of them half-remembered, and I had lost the thread of what I even had. So I pointed the method at them. An hour later I had a single page: which projects are alive, which are dying, which carry rules I must not break. The sprawl I could not hold in my head had become something I could read. That is the whole promise of the word, and it worked on my own ground first.

Then I tried to prove the deeper claim, that coordinating through a shared structure beats trading paragraphs back and forth, and I built a small experiment to test it. The first result came back null. The thing that failed was not the idea, it was my ability to measure it. I am telling you that before I tell you anything grand, on purpose. A thing that reports its own failures is the opposite of a sales pitch, and that is most of the reason the rest of this is worth your time.

Because when I went looking for why the legible page worked and the experiment did not, I fell through the floor. Under the capability there is a field. Not a metaphor for one. An actual study, with primitives and laws and an equation, of the thing the capability is good at. This is the essay about the floor.

First, the size of it. What follows is a research program, not a finished science. Some of it is solid, some of it is a sketch I am fairly sure of, and some of it is a bet I am writing down so I can be wrong in public and fix it. I am publishing it anyway, and the reason I am publishing it is itself part of the theory, which I will get to at the end.

## A level above the languages I already had

Start with a pattern. We have a formal language for quantity, and we call it mathematics. We have a formal language for truth, and we call it logic. We have a formal language for computation, and we call it computer science. Each one is a way of being precise about a kind of structure that turns up everywhere, no matter what it is made of.

There is one more kind of structure that turns up everywhere and has no settled language: cognition itself. Agents, goals, maps, beliefs, signals, constraints, and the way understanding moves and transforms and gets carried between minds. We have a thousand local theories about pieces of it and no domain-independent study of the whole shape. That gap is what complexence, the field, is trying to fill. Not the study of any one mind or any one domain, but the study of the forms, the transformations, and the navigation of complexity, independent of what the complexity happens to be about.

That is a large claim and I am making it on purpose. The word started as a capability. The capability was pointing at a subject.

I know how that sounds, and I know it rhymes with work that already exists. Smart people have built formal loops like this before me. Active Inference and the free energy principle give a rigorous account of a mind minimizing surprise through prediction and action. Boyd put orientation at the center of a loop, the OODA loop, decades ago. Cybernetics had feedback, Cynefin had the navigating of complexity. I am not claiming I invented the loop. The loop is the shared part, and I am happy to stand on those shoulders. What I think is actually new, and what this whole thing stands or falls on, is two pieces those frameworks do not carry. The cognitive form, meaning held the same across every way you can say it. And meaning velocity, the rate that meaning moves between minds, ours and the machine's. If those two buy nothing the others already give you, then this is a rebrand, and I will find that out in the open. If they buy real predictions, there is a field here.

## The loop is an equation

In the first essay I drew the loop that runs under all of it. Perception, maps, orientation, decision, action, feedback, learning, and back to perception. I drew it as a picture because that is how I had always carried it.

But when you ask what each arrow actually is, the picture hardens into something you can write down. Structure gets observed. The observation updates memory. Memory, pushed forward under constraint, becomes prediction. Prediction, measured against consequence, becomes meaning. Meaning, narrowed by a choice, becomes agency. Agency changes the structure. And the changed structure gets observed again.

You can write that down as a recursive equation. A state that transforms itself, folds the result back in, and runs the same transformation on the new state, and then does it again, forever. The capability I named is that loop run well, under load, by a person. The science is the part that says what *well* means precisely, instead of by feel.

I am not going to bury this essay in notation. The full formal version, the symbols and the system of equations, lives in [the open repository](https://github.com/OrganicArtsLLC/complexence), and I will keep building it there, in public, as a versioned thing anyone can read, fork, or argue with. What matters is smaller and stranger than the math. The loop you run in a hard conversation and the loop a living system runs to stay alive are the same shape, and the shape is writable.

## Two ways of looking at one thing

When I tried to make this rigorous, it split into two theories, and the two look like two faces of the same thing.

The first face is measurable. It treats a mind, or a team, or a human paired with a machine, as something that transforms information under constraint, and it asks what you can actually measure about that. Attention, which is finite, splits, and never multiplies. Trust, which raises how much real signal you can take from a source. Bandwidth and noise, borrowed straight from Shannon. How much of your thinking you have offloaded to tools. How deep the recursion goes, the thinking about thinking. And the one I care about most, the number the whole thing is really chasing.

I call it meaning velocity. Not tokens per second, not words, not output. The rate at which useful meaning becomes visible, transformable, and actionable. A good cognitive system, human or machine or the two together, is one that raises meaning velocity. It is a deliberately demanding north star, because it refuses to count motion as progress. A faster way to produce text that means nothing scores zero.

The second face is structural. It does not measure the process, it describes the object that moves through it. And the claim at the center of it is one line that I think is the truest thing in the whole framework.

Meaning is what survives transformation.

Take an idea and say it as a sentence, then as a diagram, then as an equation, then as code, then as a working agent. Those are five representations of one thing, and none of them is the thing. The sentence is not the idea. The equation is not the concept. The prompt is not the agent. What stays constant across all five, the part that does not break when you change the form, that is the meaning. The identity of an idea is the part that survives being moved.

Once you believe that, a useful object falls out of it. Call it a cognitive form. It is an idea held on its own, apart from any single way of saying it, carrying its meaning, its constraints, its history, and the shapes it is allowed to take. Think of a melody. You can play it on a piano or a guitar, hum it, or write it on a staff, and the melody is none of those. It is the thing that survives all of them, the part you recognize no matter how it reaches you. A cognitive form is that, for an idea. (If you write software you already know this object by another name. It is the abstract syntax tree of an idea, the structure of what something means underneath however it happens to be written.) You build the form once, then project it into an essay, a diagram, code, a prompt, an agent, a simulation, and as long as the projections keep the invariant, they are the same idea wearing different clothes.

That is the bridge from the science to the machine. [Complexence OS](/2026/06/25/complexence-os/) is the runtime where the cognitive form is the thing being passed from hand to hand. The capability orients. The science describes. The OS runs it.

## The mathematics of minds that think back

The reason any of this matters now, and not ten years ago, is that for the first time most of us are thinking next to a machine that thinks back.

Right now the interface between us and those machines is thin. A thought becomes language, the language goes into a model, an answer comes back as more language, and a great deal of the meaning leaks out at every step. We are running high-dimensional thinking through a one-dimensional straw. The point of the science is to widen the straw. If the thing you exchange with the machine is a cognitive form instead of a paragraph, the meaning has somewhere to live that does not collapse the instant you change representation. The human edits the form, the model reasons over it, agents execute it, tools render it, and the invariant holds the whole way through.

That is what I mean by the mathematics of working with minds that think back. Not prompts. Not tokens. The shared structure that lets human and machine cognition amplify each other instead of only trading text back and forth.

## The strange part: using it on itself

If a cognitive form is an idea held across all of its representations, then complexence is one. This essay is a projection of it. So is the first essay, so is the spec, so is the open repository, so is the private research underneath. None of them is the whole thing. The word stays a little loose on purpose, and now I have a formal reason for the looseness instead of only an instinct. A self-referential form can never fully contain itself. There is always a remainder it cannot fold inside its own description. The looseness is not vagueness. It is that remainder, and the theory says it is guaranteed.

Which means refining the definition of complexence is complexence, executing on itself. The theory has an operator for a form that operates on its own structure, and tightening these essays against the research is literally that operator running. I did not plan the recursion. I noticed it after the fact.

And it settled a decision I had been stuck on for days.

I had been keeping the formal core private, telling myself I would publish once it was finished and clean. But the theory has a law that kept pointing back at me. Power without feedback drifts. A system that reflects without correcting from the outside hallucinates. A foundation developed entirely in private accrues error it cannot see, because the only thing that catches the error is contact with the world. People using it, people arguing with it, people proving parts of it wrong. The feedback is the whole mechanism. Keeping the science private to protect it is exactly the move the science says will rot it.

So I am publishing it. The word, the loop, the two faces, the cognitive form, the open questions, all of it, here, first, with my name on it. It is licensed so that anyone can build on it and is required to credit where it came from. I would rather own a thing that grows in the open than guard a thing that quietly drifts in a drawer. That is not a marketing decision dressed up as a principle. It is the principle. The theory told me to publish, and publishing it is the theory working.

## Where this actually is

One more time, plainly, because the worst thing I could do to a real idea is oversell it.

This is a research program. The measurable quantities have to actually be measured, in real people and real systems, and shown to predict something, before any of it earns the word science without a caveat. Meaning velocity is a clean north star and right now it is a definition, not a number I can hand you. I have started, though. I built the first measurement harness and ran the first experiment, the shared structure against the plain exchange of text, and at the size I could afford it came back inside the noise. No signal yet. What it taught me is that the measuring is the harder half, harder than the idea, which is exactly the thing the theory warns about itself. That is the first data point, and it sits in the open repository with the null written down next to the hope. The two faces are almost certainly one thing, and proving that cleanly is the open problem I most want solved. The very bottom of the stack, the question of which primitive is truly first, is unsettled. I am writing the unsettled parts down on purpose, because a field that hides its open edges is just a brand.

But the shape is real, and it is the thing I have carried for a year without a word for it. There is a capability, the person standing inside complexity and still choosing. There is a machine that runs it, so the structure work happens outside the head. And under both there is a science of how minds, the old ones and the new ones, orient, transform meaning, and amplify each other.

I coined a word for what a person does, and it names a field. I am going to spend a long time down here, and I am going to do it out loud.

## More on the idea underneath

- [Complexence](/2026/06/17/complexence/), the capability this whole field is the science of.
- [Complexence OS](/2026/06/25/complexence-os/), the machine where the cognitive form is the kernel object.
- [Engineering Orientation](/2026/07/08/engineering-orientation/), the first field report, where the program gets a runtime, laboratories, and its first pre-registered experiment.
- [Making complexity visible](/2026/06/02/making-complexity-visible/), the mission, and [coherent complexity](/2026/06/02/coherent-complexity/), the framework, the two layers above the capability.
- [The open repository](https://github.com/OrganicArtsLLC/complexence), where the capability map, the method, and the formal science all live as one versioned spec.

---

*The Science of Complexence is an open research program, licensed Creative Commons Attribution 4.0, [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/). Use it, build on it, argue with it, and credit where it came from.*]]></content:encoded>
      <pubDate>Sun, 28 Jun 2026 18:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/28/science-of-complexence/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/science-of-complexence.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>Complexence OS</title>
      <link>https://joshuaayson.com/2026/06/25/complexence-os/</link>
      <description>Complexence is the capability of staying oriented inside complexity. Complexence OS is the rough machine I built today to run it: you talk into a file, one Chief of Staff agent sorts what you said and hands the rest to a few specialist roles, and you review only the exceptions. Day one of going from AI assisted to agent director. The method is open source; your data stays yours.</description>
      <content:encoded><![CDATA[I built this today. Not over a careful month. Today, on a day I had no bandwidth to build anything, out of plain need. All week I had been a little stunned at what happens when you stop asking an AI for one thing at a time and start chaining the steps, letting one hand off to the next. So tonight, running on empty, I breathed life into a setup I had been sketching, wired it into a Slack app I made last year and never finished, and watched it half stand up. It semi lives. It still has issues. But it is pointed the right way, and it is already a different way of working than I had this morning.

Here is what it does, on the day it was born. I open a note and talk into it, say whatever is in my head, and save. That is the whole obligation. Some hours later a single agent has read it, cleaned up my run-on speech, sorted each piece, written a short brief, and handed the messy parts to the right helper. I read five sections and clear the two that need me. When it works, the rest already happened.

I have been calling the thing underneath all of this [Complexence](/2026/06/17/complexence/), the capability of standing inside a system larger than yourself and still choosing. That essay was about the human quality. This is the machine I started building to run it, and I put the method online tonight, rough as it is, for anyone. I am calling it Complexence OS.

## The name is older than the system

I have been circling this for a year. The name came first. I had a Marcus in my head well before any of the code, a right hand whose only job was to keep my own life legible to me. Last spring he took his first real shape as a Life OS dashboard, a wall of counts and tags and heatmaps that mirrored my days back at me. It was genuinely interesting, and it never once acted. It could show me the state of things and then just sit there, a beautiful read only mirror.

So I overcorrected and chased a cognitive twin, a model of me that could reflect and decide alongside me, recursive and ambitious and mostly theory. That detour was worth it because it taught me where the real edges were. Tonight all of it collapsed into something far humbler than any of the grand versions, and that humble one is the first that actually moved. The dashboard wanted to display. The twin wanted to think. What worked was talk, route, review. And the right hand I sketched a year ago finally has a name that sticks: the router is Marcus. I named him for Marcus Aurelius, who wrote his Meditations to no one but himself. That is close to what the daily note actually is, a private discipline for staying steady inside something too large to control.

## The bottleneck was never ideas

For years I told myself the problem was that I did not have enough good ideas. That was never true. The ideas show up fine, usually in the worst possible moment, in the car or mid walk or right before sleep. The problem was the desk. The capturing, the sorting, the writing up, the filing, the remembering where I put it. The structure work. By the time I sat down to do it the energy was gone and the idea had gone cold, and I called that a discipline problem when it was a friction problem.

One of the things I keep coming back to about complexence is that you cannot hold the whole system in your head and you were never supposed to. You build the map outside your head so the head is free to do the part only it can do. Complexence OS is that move, made literal. It is the externalized half of the capability. The machine holds the structure so I can spend myself on judgment instead of filing.

## How it actually works

The shape is small on purpose.

```text
voice in  ->  one router  ->  specialist roles  ->  durable artifacts  ->  weekly review
```

You capture by speaking into a dated inbox file. You route the whole inbox through one prompt, a Chief of Staff. It does not try to be clever. It cleans each spoken entry into readable prose without changing your words, classifies every item, scores how sure it is, and either handles the item or hands it to a specialist. Then it writes one daily brief with five sections: your top three, what it processed, what is waiting on you, what is blocked, and one forward action. You read the top three and the blockers. You ignore the rest, because the rest is done.

Behind the router is a capped set of specialist roles, six to start. One maps the terrain of my repositories so I can see what changed. One drafts and stages writing. One keeps a census of the system. One plays critic. None of them act on the world without me. The cap matters as much as the roles. The temptation with agents is to keep adding them until you have a committee you now have to manage, and a committee is just complexity wearing a helpful face. Six roles I can name and trust beats twenty I have to supervise. A few of them are barely past a prompt and a hope right now. On day one that is fine. The shape is the point, and the shape held.

The reviewing is the discipline, and it is deliberately tiny. A five section brief, mostly blockers. If I am tired, capture is enough, and the system tolerates a day or two of lag without breaking. The point of the whole design is that on my worst day the obligation is still just: talk into the file, save. A system is for the version of you that won't listen; [I learned that one the expensive way](/2026/07/17/knowing-isnt-a-system/).

## The rule that makes it safe to hand over

The reason I will let an agent run unattended is that it physically cannot do the dangerous things. When the Chief of Staff runs on its own, it has file tools and nothing else. No posting, no pushing, no deploying. If I ask it to publish something, it does not publish. It stages the thing privately and leaves me a single yes or no decision. Going public is always me, by hand, on purpose.

That is the line the whole system is built around, and it is the same instinct as the [antifragile](/2026/05/30/living-with-antifragility/) one. Let the machine take the volatility you do not want, the drudgery and the filing and the first draft, and keep for yourself the few moves that are irreversible. Automate the recoverable. Gate the permanent. An assistant you have to watch every second is not saving you anything. One that is structurally incapable of the catastrophic case is a different kind of tool.

## Why I made the method public

I open sourced the method, not my life. The public repository, [the Complexence repo on GitHub](https://github.com/OrganicArtsLLC/complexence), holds the specification, the role prompts, and blank templates. It does not hold a single one of my captures or outputs. Those live in a private instance the repository is built to keep out, with a guard that refuses to commit your real data. The method is the part that generalizes. The data is the part that never should.

The prose is licensed CC BY 4.0 and the scripts are MIT, so you can take it, adapt it, run it at work or for a project, and change only the nouns: your own categories, your own arenas, what a finished artifact means to you. I did not want to ship an app. Apps decide for you. This is a method you instantiate, which means you stay in charge of the shape of it.

The reason it is public is that complexence is [trained, not issued](/2026/06/17/complexence/), and the training goes faster when the scaffolding is already standing. I spent a long time building the trellis. There is no reason you should have to build the same one from scratch before you get to the part that actually grows you.

## What it is really for

I did not build this to be productive in the magazine sense. I built it because the world keeps getting more complex and I refuse to answer that by making myself smaller. The machine is not the point. The capability is the point. The machine just clears the desk so the capability has room.

You talk. One agent sorts it. You review only what truly needs you. Everything else becomes a durable artifact you can find later, and when the loop holds, it closes on its own. That is the externalized half of standing inside complexity without coming apart. I keep the judgment. The system keeps the structure.

This is day one. For a couple of years my work has been AI assisted, me at the keyboard with a fast helper at my elbow. Tonight it crossed into something else: me directing a small set of agents and reviewing what they hand back. From AI assisted to agent director, in one tired evening, with a setup that half works and a year-old Slack app holding part of it together. It will grow and get less brittle over the coming days, and I will post a followup when it has earned one. The direction is what I wanted to mark. It starts, still, with me talking into a file and saving.

## How I am actually doing it

None of this is fancy, and that is the point. The whole thing runs on one Mac at home. Capture is dumb and local. I hit an iOS Shortcut on my phone, talk, and it drops the recording into a Shortcuts folder in iCloud. A small loop on the Mac watches that folder, and when a new memo arrives a local Whisper model (faster-whisper, the small English model, on the CPU, no cloud and no API) turns it into text and writes it into the day's note. The thing that hears me never leaves the machine. That voice path is one of the two ways in. The other is typing to Marcus in Slack, for the times I would rather not talk. Two different doors, the same route, the same place it ends up.

The piece I did not expect to need was Slack. Partway through I realized a capture-only loop is half a loop. If the system can take what I say but cannot say anything back, I am still tied to a terminal to find out what it did. So I wired in a Slack app I built last year and never finished, two-way, over Socket Mode. Now the loop talks back. It DMs me the brief and the blockers, and I can DM it a new thought from my phone without opening a terminal or even speaking. That one change is what turned it from a script I run into a thing I have a conversation with.

The rest, for now, is held together with tape, and I am fine saying so. I reach the Mac from my phone over Tailscale, a small private network, with Termius as the terminal. The session drops on me constantly, which is half the reason the Slack back channel matters as much as it does. I keep meaning to live inside tmux so the work survives a disconnect, but its scrolling fights me, so for now I just reopen Termius and resume the agent session where it died, and I have learned to tell the agent to run anything long as its own detached process so a dropped phone connection cannot kill it halfway. It is day one, and it looks like day one. This very post got staged that way, by an agent that finished the job after my session had already fallen over.

So there are two ways in, voice and Slack, and they both lead to the same place: one dated markdown file that gets written once and is never edited after. Everything downstream, the briefs, the artifacts, the dashboards, is derived from that one file. Two inputs, one source of truth, written once. That rule is boring, and it is the whole reason I trust the thing not to quietly rewrite its own memory.

I know there are a dozen better ways to build this, and people who would do it cleaner in an afternoon. That is fine. This is iteration one, my first rough pass at it, and I like the spirit of the thing more than I am bothered by the seams. Mostly I am just excited about what comes next.

## More on the idea underneath

- [Complexence](/2026/06/17/complexence/), the capability this whole system exists to grow, and [The Science of Complexence](/2026/06/28/science-of-complexence/), the formal floor under it, where the cognitive form this machine passes around is the kernel object.
- [Making complexity visible](/2026/06/02/making-complexity-visible/), the mission, and [coherent complexity](/2026/06/02/coherent-complexity/), the framework under it.
- [Living with antifragility](/2026/05/30/living-with-antifragility/), the instinct behind gating the irreversible.
- [Finding Edgar Morin](/2026/07/12/finding-edgar-morin/), the man who worked this same mountain for eighty years as epistemology while I work it as operations.]]></content:encoded>
      <pubDate>Thu, 25 Jun 2026 22:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/25/complexence-os/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/complexence-os.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>Germane Friction</title>
      <link>https://joshuaayson.com/2026/06/24/germane-friction/</link>
      <description>The fight over whether AI is good or bad is the wrong fight. AI is a friction-removal engine, and there are two kinds of friction: the kind that is building you, and the kind that is only taxing you. Telling them apart, in the moment, is the whole skill.</description>
      <content:encoded><![CDATA[A while ago I ran an argument against myself, on purpose, and it ended somewhere I did not expect.

I started by building the strongest case I could that leaning on AI is a mistake: that it hides its costs, decays the work, drains the worker, starves the next generation, and flattens the culture. I made it [as hard as I could](/the-case-against-ai/). Then I turned around and built the opposite case, that AI is just the next rung on a [seventy-year ladder](/the-case-for-ai/) of removing effort that was never building anyone, the calculator move for knowledge work. And that one came out stronger.

But winning was not the feeling I was left with. The feeling was that I had written one essay twice. The two cases were not opponents. They were the same observation, read once as a loss and once as a gain. Both of them were about a single thing, and once I saw the thing I could not unsee it. They were both about friction, and they were each only looking at half of it.

## AI is a friction-removal engine

Strip away the specifics and that is what the technology is. It collapses the distance between intending something and having it. You want a function, a paragraph, a summary, a plan, and the gap where you used to have to produce it by effort gets very small. Every accurate description of what AI does, good or bad, is a description of removed friction.

So the two sides of the debate are not really disagreeing about AI. The optimist looks at the removed friction and says: that was overhead, that was waste, removing it is pure gain. The pessimist looks at the same removed friction and says: that effort was the gym, that was where the capability got built, removing it is quiet atrophy. They are pointing at the identical fact. They are assigning it opposite signs. And they are both right, about different friction, which is why neither of them can win and why the argument goes in circles forever.

Because there are two kinds of friction, and the entire confusion comes from using one word for both.

## Two kinds, named plainly

I am going to borrow a word from the learning sciences, because they figured this out a long time ago and have the cleanest version of it.

When you do hard mental work, the effort splits into two kinds. Some of it is doing nothing for you. It is the noise: the badly organized interface, the boilerplate you have typed a thousand times, the syntax you already understand, the lookup, the ceremony, the part where you fight the tool instead of the problem. The researchers call this **extraneous load**, and their advice about it is unambiguous. Remove it. All of it. It is pure tax, and it builds nothing.

The other kind is the effort that is actually constructing something inside you. The struggle to understand, the work of building the model in your head, the fight to find the idea that was not obvious, the slow formation of judgment that only comes from having done the thing yourself. They call this **germane load**, germane meaning relevant, the effort that is genuinely germane to learning. And their advice about this one is the exact opposite. Protect it. This is not waste. This is the work. This is the part where you become someone who can do the thing.

So let me name the distinction the way I will use it for the rest of this. **Extraneous friction is the effort that is only taxing you, and builds nothing. Germane friction is the effort that is actually building you while you spend it.** Same word, friction, two completely different things wearing it.

And now the whole debate resolves, because you can finally see what each side was looking at. The case for AI is built entirely from examples where the friction was extraneous: the newcomer fighting syntax, the boilerplate server, the toll booth that kept people out. Remove that and the optimist is simply correct, it is pure gain, take it every time. The case against AI is built entirely from examples where the friction was germane: the deep work that was sharpening a senior, the apprenticeship that was forming a junior, the struggle for the sentence that was making a writer. Remove that and the pessimist is simply correct, it is atrophy, and you will not even feel it happening. They were never in disagreement. They had each grabbed one kind of friction and mistaken it for the whole.

## The tool cannot tell which is which

Here is the part that makes this hard instead of just tidy, and it is the part I keep coming back to.

The AI does not know the difference. It cannot. When you ask it to do the thing, it has no way of knowing whether the effort it is sparing you was the tenth identical CRUD endpoint, pure extraneous tax, or the one piece of genuine reasoning that was about to teach you something you would have carried for a decade. It removes both with the same cheerful confidence and the same little spinner. To the engine, germane friction and extraneous friction are identical. They both look like work you would rather not do.

Which means the discrimination cannot live in the tool. It has to live in you. Every time you reach for AI, there is a question underneath the reach, usually unasked: which kind of friction am I about to remove? Is this the boilerplate, or is this the thinking? Is this the toll booth, or is this the gym? Get that question right and AI is the best thing that ever happened to your work, because it lets you delete the tax and keep the training. Get it wrong, reach for the tool on the germane friction because germane friction is hard and the tool makes it feel optional, and you will trade the version of yourself you were about to become for a slightly faster afternoon, over and over, until you are someone who ships and cannot think.

This is why the productivity studies disagree with each other. The newcomer getting fifty percent faster and the senior getting nineteen percent slower are not contradicting each other. They are the same law seen from two sides. The newcomer was drowning in extraneous friction and the tool drained the pool. The senior had already drained their pool years ago, and the only friction left in their deep work was germane, so the tool could only get in the way of it. The number is not a fact about AI. It is a fact about which friction you had left.

## The skill is telling them apart in the moment

So the actual skill of this era is not prompting, and it is not knowing which model to use, and it is certainly not the binary of being pro-AI or anti-AI, both of which are just ways of refusing to do the discrimination. The skill is the discrimination itself. It is being able to feel, in the moment of reaching for the tool, whether the friction in front of you is the kind that is building you or the kind that is only taxing you, and then routing accordingly: delete the tax, keep the training, and spend the time the tax used to cost on the harder layer the tool just exposed.

That last move is the one almost everybody skips. When you let AI remove genuine extraneous friction, you get a surplus of attention back. The thing to do with that surplus is to spend it up a level, on the harder problem, the one the drudgery used to crowd out. The failure, the thing that turns even good AI use into slow decline, is to pocket the surplus as idleness, to let the freed attention evaporate. AI removing the right friction is only a gift if you reinvest what it gives you. Otherwise you have just bought a more comfortable way to stop growing.

I have a name for the capability this all requires, because it is the same capability I keep finding underneath everything I write about. It is [complexence](/complexence/): the human ability to stay oriented inside something complex without fragmenting, to hold the map yourself instead of handing it to whatever offers to hold it for you. The friction discrimination is complexence pointed at AI. The tool is constantly offering to hold the map for you, to remove the effort of orienting, and some of that effort is extraneous and you should let it, and some of that effort was the only thing keeping you able to navigate at all. Knowing which is which, while a confident machine insists it does not matter, is exactly the capacity of standing in complexity without letting it, or the tool, do your thinking for you.

## Where I actually stand

I am not against AI. I run agents daily, and I would not give them back. I am also not a believer in the way the loudest optimists are believers, because I have watched myself reach for the tool on germane friction precisely because it was germane, because it was hard, and felt the small private cost of having skipped the rep.

So the position is not a verdict on the technology. It is a practice, and it is a demanding one. Use AI without mercy on extraneous friction; there is an enormous amount of human effort that was never building anyone, and protecting it out of nostalgia is its own kind of foolishness. Guard germane friction like it is the thing your future self is made of, because it is. And accept that the line between them is not fixed, that it moves with who you are and what you are trying to become, that the same task is extraneous friction for the expert and germane friction for the apprentice, and that nobody, no tool and no essay, can draw the line for you. You have to draw it yourself, in the moment, again and again, which is the work, and which is also the only version of using AI well that I have ever found to be true.

That is the coin. One face says removing friction is freedom and the other says removing friction is decay, and they are the same coin, and the whole of the skill is knowing, each time you flip it, which friction you are spending. I built [the case against](/the-case-against-ai/) and [the case for](/the-case-for-ai/) at full strength because I had to, because you cannot see the coin until you have held both faces up to the light and found them attached. They were never two arguments. They were one, about friction, waiting for someone to say which kind.]]></content:encoded>
      <pubDate>Wed, 24 Jun 2026 23:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/24/germane-friction/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/germane-friction.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>The Case For AI, Made Properly</title>
      <link>https://joshuaayson.com/2026/06/24/the-case-for-ai/</link>
      <description>Most defenses of AI are about productivity, and they are weak. The strong case is older and bigger: this is the next rung on a seventy-year ladder of removing effort that was never building anyone. Here it is, made at full strength.</description>
      <content:encoded><![CDATA[This is the second side of a three-part argument. The first side, the [case against](/the-case-against-ai/), is real and I made it as hard as I could. This one came out stronger, and I want to show you why rather than just assert it. What I actually think, having built both, is [here](/germane-friction/).

Most defenses of AI are bad, and they are bad in the same way. They lead with productivity. It writes your boilerplate, it drafts your email, it saves you twenty minutes, look how fast. That argument loses, and it should, because the other side can always point to the [study](/the-case-against-ai/) where the experienced developers got slower, and to the code that decayed, and to the mind that atrophied. If the whole case for AI is a stopwatch, the case for AI is fragile.

The real case is older and much larger, and it has nothing to do with saving twenty minutes. It is this: removing human effort from work is the single most reliable form of progress our species has, we have done it over and over for centuries, it has terrified people every single time, and they have been wrong every single time in the same way. AI is the next instance of the oldest good move we know how to make.

## Start with where the gains are actually real

Be specific, because vagueness is where this argument usually goes soft.

In controlled studies, developers given AI on well-scoped, from-scratch tasks finish dramatically faster, in one well-known trial around fifty-five percent faster on building a server from nothing. The enterprise field studies cluster lower but still solidly positive, in the thirty to fifty percent range for the right kind of work. These are not vibes. They are measured, repeated, and large.

Now hold that next to the famous result on the other side, the one where experienced developers got nineteen percent slower. People treat these as a contradiction. They are not. They are a map. The slowdown happened to senior engineers doing deep work in mature codebases they already held entirely in their heads, which is the one situation where there was no effort left to remove, only context to re-explain to a machine that did not have it. The speedups happen on greenfield work, on unfamiliar territory, on the vast middle of ordinary tasks. The two findings together do not say AI is good or bad. They draw a line. On one side of the line the effort being removed was real waste, and the tool is a rocket. On the other side the effort was the thinking itself, and the tool is a drag. That line is the whole story, and I will come back to it.

## It lifts the person with less, not the person with more

Here is the part the productivity framing buries, and it is the strongest single thing you can say for AI.

Across study after study, the people who gain the most are the ones with the least. Less experienced developers, lower-tenure workers, people earlier on the curve: they get the biggest lift, consistently, while the experts gain little or sometimes lose. This is the opposite of how most powerful tools work. Most leverage compounds advantage; the people who already have the most get the most out of it. AI, at least at this stage, does the reverse. It is most valuable to the person standing at the bottom of the cliff, looking up at a wall of syntax and convention and accumulated jargon that used to take years to scale.

Take that seriously and the moral weight of the argument flips. The friction AI removes is, disproportionately, the toll booth that kept people out. The hours you spent memorizing the incantations, fighting the environment, learning which of forty ways to do a thing was the blessed one: that was never the work. It was the hazing. It was the cost of admission that happened to be highest for the people with the least time and money and prior access. A tool that lowers that toll is not a convenience. It is a widening of the door.

## The ladder is seventy years long and points one way

Now zoom out, because this has all happened before, and the pattern is almost embarrassingly clear.

Programming began as physically rewiring machines, then as machine code, raw numbers a human had to think in. Then assembly let you use names instead of numbers, and the people who thought in raw numbers said the names would make programmers soft and stupid. Then compilers let you write something close to human language and threw away the assembly for you, and the assembly programmers said the same thing: real programmers control the machine, this abstraction will rot the craft. Then high-level languages, then libraries you did not write, then garbage collection that managed memory so you did not have to, then no-code tools, then the cloud. Every rung removed a layer of effort that the previous generation considered essential to the discipline. Every rung drew the identical objection: you are removing the struggle that makes a real practitioner, and you will get a generation that cannot do the fundamentals.

And every time, the objection was true in the small and wrong in the large. Yes, most working programmers today cannot hand-allocate registers, and a few of them probably should be able to. But the abstraction did not destroy the field. It moved the floor of effort up to a more valuable layer. Nobody mourns the lost art of manual memory management as a tragedy for human capability. We took the attention that used to go into the drudgery and spent it on harder, higher things, and the field got bigger and better and more open every single time.

The calculator is the cleanest case. It did not end mathematics or rot the mathematical mind. It ended arithmetic drudgery and freed a generation to spend its attention on structure and proof and modeling, the parts that were actually mathematics. The fear was real and specific and it simply did not come true. AI is plausibly that move, the calculator move, for a sprawling class of cognitive work that has never had its calculator before.

## The harms are contingent, and contingent harms get fixed

The case against leans hard on real damage: decayed code, homogenized writing, juniors who do not learn. Take each one seriously and notice the same property in all of them. None is a law of the tool. Each is a way of using it badly that we already know how to use better.

Homogenization is the clearest. The studies that find AI flattening creativity also find the flattening disappears, and sometimes reverses into more diversity than the human baseline, the moment people use varied prompts and varied models instead of all leaning on the same default. The sameness was not the AI. It was everyone using it the laziest possible way. Junior developers have the same answer arriving: the smarter firms are rebuilding the apprenticeship around the tool, having new engineers spend months reviewing AI output, writing the tests, pairing on the design, learning judgment instead of typing. The decayed code is a discipline problem, and we have a long history of inventing the discipline a powerful tool demands after we get the tool, not before.

Contingent harms are the kind that engineering removes. Intrinsic gains, the lifted newcomer, the removed toll, the freed attention, are the kind that bank. Betting against a tool because its first-draft misuse is ugly is betting against every transformative technology in history at exactly the wrong moment.

## The crack in my own case

The case has to find its own weak point, so here is mine.

My whole argument rests on one claim: the effort AI removes was never building anyone, the way arithmetic and register allocation were never the real work. The compiler removed drudgery and left the thinking. But that is precisely the thing AI might not do. Every prior rung on the ladder automated the mechanical layer beneath the thought and left the thought alone. AI is the first tool that offers to do the thinking itself, the design, the judgment, the sentence you had not yet figured out how to write. If it only ever removed the arithmetic of knowledge work, my case would be airtight. The worry is that it does not stop there, and that it cannot tell the difference between the drudgery and the thought, and that it will hand you both with the same cheerful confidence.

So I have proven less than it sounds like. I have proven that removing effort is usually progress, and that this tool removes a great deal of effort that was pure toll and pure waste. What I have not proven is that it only removes that. The [other side](/the-case-against-ai/) is making the same bet from the opposite end, and both of us are really arguing about one thing, [friction](/germane-friction/), and which kind of it is on the table. I had to build this case at full strength to see that winning it was not the point. The point was the line I kept drawing and stepping over: the line between the effort that was building you and the effort that was only ever in your way.]]></content:encoded>
      <pubDate>Wed, 24 Jun 2026 22:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/24/the-case-for-ai/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/the-case-for-ai.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>The Case Against Letting AI Think For You</title>
      <link>https://joshuaayson.com/2026/06/24/the-case-against-ai/</link>
      <description>AI does not destroy your work in front of you. It moves the cost somewhere you cannot see: to later, to the invisible, to the version of you that stops getting built. The strongest case against leaning on it, made in full.</description>
      <content:encoded><![CDATA[This is one side of a three-part argument. I built the opposite case too, and it came out [stronger](/the-case-for-ai/). The resolution, where I actually stand, is [here](/germane-friction/). But I want to make this side properly first, because it deserves better than the version people usually wave away.

In early 2025, sixteen experienced developers sat down to do real work in repositories they had maintained for years. For half their tasks they were allowed AI tools. For half they were not. Before they started, they expected the AI to make them about a quarter faster. After they finished, they were sure it had, by about a fifth. Then the researchers measured what actually happened. With the AI, they were nineteen percent slower.

That study, run by METR, is the most uncomfortable single fact in this whole debate, and not because of the slowdown. The slowdown is arguable; it was a specific cohort doing deep work in code they already knew cold, which is the exact case where AI helps least. What should bother you is the gap between the nineteen percent slower they measured and the twenty percent faster the developers felt. These are good engineers. They could not feel the truth about their own productivity. The tool did not just change their speed. It changed their ability to perceive their speed.

That is the shape of the entire case against leaning on AI. It does not break your work in front of you, where you would notice and stop. It moves the cost somewhere you cannot see.

## It moves the cost to later

Start with the artifact, because it is the easiest place to watch the cost migrate.

GitClear looked at more than two hundred million lines of code written between 2020 and 2024, the window where AI assistants went from novelty to default. The trend lines all point the same way. Copy-pasted code climbed. Refactoring, the work of taking something that works and making it cleaner so the next person can stand on it, fell by roughly sixty percent. Duplicated blocks multiplied. Churn, the share of code rewritten within two weeks of being committed, went up: more code that was wrong on arrival.

None of this is the AI writing garbage. The individual suggestions are usually fine, even good. The problem is what gets skipped. Designing a reusable abstraction is slow and effortful, and an autocomplete that will hand you a working copy of the nearby thing makes skipping that work feel free. So you skip it. Then you skip it again. Each skip is invisible and cheap. The bill arrives months later, in a codebase that nobody refactored because refactoring stopped being the path of least resistance, and now every change touches eight near-duplicates of the same idea.

This is technical debt, but worse, because technical debt is usually a decision. Someone says, out loud, we will do this the quick way now and pay for it later. The AI version is debt you take on without ever deciding to. The cost was simply moved downstream, past the point where you were paying attention.

## It moves the cost to you

Now the harder migration, because this one comes out of the person.

There is a growing pile of research, across coding and writing and reasoning, on what happens to a mind that offloads its thinking to a machine. The findings are consistent and they are not subtle. Heavy reliance correlates with weaker critical thinking. People given an AI assistant give up sooner when it is taken away and perform worse on their own afterward. Researchers have a clinical word for it: deskilling. The capability you stop using does not hold steady. It drains.

The mechanism is not mysterious, and it is worth being precise about, because it is the hinge of the whole argument. The struggle you are tempted to delegate is, very often, the exact struggle that was building you. The half hour of being stuck on a problem is not a tax on the learning. In the learning sciences it has a name, desirable difficulty, and it is the part of the work where the understanding actually forms. The fight to find the non-obvious sentence is where you become a writer. Hand the fight to a machine and you get the sentence. You do not get to become the writer.

This is the trade that feels like a gift and is not. Every time you let the tool do the part that was hard, you get the output and you skip the rep. One skipped rep is nothing. A thousand skipped reps is a different person, one who can no longer do the thing they used to be able to do, and who may not even remember that they used to.

## It moves the cost to the next person

Watch the cost leave the individual and fall on a whole generation.

Junior engineers are not learning the way they used to, because the work juniors learned from is exactly the work that AI now absorbs. The boring function, the careful debugging, the slow apprenticeship of seeing what your choices cost two weeks later: that was never just output. It was how an engineer got made. When the tool does it instead, the company gets the output and the human gets none of the formation.

The hiring numbers have started to follow. Entry-level developer postings have fallen hard since 2022. Senior roles have held or grown. Read that forward and the picture is grim in a slow way: if you stop making juniors, you stop making the mid-levels they would have become, and you stop making the seniors after that. The pipeline that produces the people who can actually judge AI's output is being quietly defunded by the same tool that made it look optional. Learning cannot be outsourced. But hiring is trying to outsource it, and the bill comes due in about a decade, on someone else's watch.

## It moves the cost to the culture

The last migration is the widest and the easiest to miss, because you cannot see it from inside one person's work at all.

Large language models converge. Independently trained models from different labs on different continents produce strikingly similar output, measured in one study at around eighty percent overlap. When people write with AI, their individual pieces often get more polished and the whole set gets less diverse. Researchers call the attractor an artificial hivemind: not one voice silencing the others, but a million voices drifting toward the same mean because they are all leaning on tools that pull in the same direction.

Run that across a culture for a decade. Not censorship, nothing so dramatic. Just a slow flattening, a narrowing of the range of things that get said, because the frictionless path always runs through the middle of the distribution. The weird sentence, the idiosyncratic structure, the idea that sounds wrong until it doesn't, these are precisely the things a model trained on the average will smooth away, gently, every time, for free.

## The crack in my own case

Here is where the case has to turn on itself.

Every harm I just laid out is a harm of how the tool is used, not a property of the tool. Slower in deep work, fine: it is faster in shallow work. Code decay: that is a discipline that AI happens to make easy to drop, not one it forbids. Deskilling: it offloads the struggle that builds you and also the struggle that just wastes you, and I have not yet told you how to tell those apart. Homogenization drops back to baseline the moment people use the tools with any deliberateness at all.

Notice what that means. I built this whole case on a single move: the cost gets hidden and paid later, by you, by the next person, by the culture. But I never said which costs were worth paying. I treated all friction as sacred, and that is not true, and the strongest reply to everything here is to point at the mountain of human effort that was never building anyone and ask why I am so eager to protect it.

That reply is real. I made it [in full](/the-case-for-ai/), as hard as I could, and it came out stronger than this did. Both of these essays are one claim about the same thing, read with opposite signs, and the thing is [friction](/germane-friction/). The question is not whether AI removes it. It is which kind it is removing, and I had to argue both sides at full strength before I could see that the fight was never really about AI at all.]]></content:encoded>
      <pubDate>Wed, 24 Jun 2026 21:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/24/the-case-against-ai/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/the-case-against-ai.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>Why Thirty-Three Repositories Needed a Census</title>
      <link>https://joshuaayson.com/2026/06/23/why-my-repos-needed-a-census/</link>
      <description>I had thirty-three git repositories and treated all thirty-three as if they were on fire. The fix was not more discipline or a better tool. It was a census: an inventory, an edge, and a rule for what counts as alive. Domain cartography applied to my own sprawl.</description>
      <content:encoded><![CDATA[I have thirty-three git repositories under one organization, and for a long time I treated all thirty-three as if they were on fire.

Every one of them sat in the same folder, at the same brightness, with the same silent claim on my attention. Opening the directory felt like walking into a room where thirty-three people all start talking at once. Some of those projects were genuinely active. Some had not been touched in months and were fine that way. A few were finished. One or two were probably dead and just had not been told. But nothing in the way I had them arranged said which was which, so my brain did the only thing it could with an undifferentiated pile: it treated the whole pile as urgent, and I paid an anxiety tax every single time I looked at it.

The reflex, when this happens, is to assume the problem is you. You need more discipline. You need to finally learn the tool that will organize everything. You need a monorepo, or a better dashboard, or a weekend of cleanup. I tried versions of all of that, and none of it touched the actual problem, because the actual problem was not effort and it was not tooling. It was that I had never made the domain legible to myself. My bottleneck was never knowledge. It was governance.

## Sprawl is a symptom, not the disease

Here is the thing I had backwards. I thought the sprawl was the problem. The sprawl was a symptom. The disease was that there was no map, and with no map, every repository defaulted to the same status: equally alive, equally my responsibility, equally on fire. A collection only becomes a burden when you have no way to say that some of it is at rest.

That reframing is the whole move, and it comes straight out of the practice I have been writing about, [domain cartography](/domain-cartography/), the craft of making a complex domain legible enough to navigate. My repositories were a domain. A real one, with parts and forces and edges, and I had simply never charted it. I had been living inside it by memory, and memory is exactly the thing that fails at this scale. So I stopped trying to remember my way through thirty-three repos and started trying to map them. The map has a name. It is a census.

## What a census actually is

A census is not a cleanup. Cleanup is where most people start, and it is a trap, because you cannot clean a domain you have not yet described. You end up making a hundred small irreversible decisions in a fog. A census comes first. It is just the first three layers of [the method](/2026/06/23/how-to-map-a-domain/) run on a real domain, and it goes in order.

**First, the inventory.** I wrote down all thirty-three, fast, flat, no sorting. This is the primitives layer, and it did the thing it always does: the moment the pile became a numbered list, it stopped being infinite. Thirty-three is a lot. It is also a specific, finite, countable amount, and a specific finite amount is something a person can actually govern. The fog was never the repos. The fog was that I had never once made them hold still long enough to be counted.

**Then, the edge.** I decided what this map was and was not. This census covers code repositories under the organization. It does not cover my notes, my writing pipeline, or the private life systems that live elsewhere. Those are real, and they are other maps. Drawing that boundary is what kept the census from ballooning into a map of my entire working life, which would have been as useless as no map at all. An edge is what makes a map finishable.

**Then, the lanes.** This is the part that changed everything. I gave every repository one of three statuses, and the three are the heart of it: **active, maintenance, archive.**

- **Active** means it is being worked on now. It is allowed to ask for my attention. There are not many of these, and that is the point.
- **Maintenance** means it works, it ships, it gets a security bump or a small fix when it needs one, and it is otherwise allowed to be quiet. It is not on fire. It is not supposed to be on fire.
- **Archive** means it is done, or it is dead, and either way it is preserved and closed. It does not get feature work. It is allowed to be finished.

That is the governance layer, and writing those three definitions down, once, in calm, did more for my actual workload than any tool ever has. Because the lanes are decisions made in advance. "Archived repos do not get feature work" is a rule I set once and never have to relitigate at midnight when some old project whispers that maybe I should go fix it. The lane already answered. The governor already spoke.

## What the census captures

If you do this yourself, capture more than the name and the lane. The fields that earned their place on mine: what the repository actually is, in one sentence, its lane, when it was last actually touched, what depends on it, and what would have to be true for it to change lanes. That last field is quietly the most important one, because it is what keeps the census from going stale. A map that cannot tell you when to redraw it is already decaying. "This moves from active to maintenance when version one ships" means the census knows its own future, and updating it becomes a small act of upkeep instead of another overwhelming project.

## The tax it removed

The repositories did not change. I did not delete a single one or write a line of code. All that changed is that the domain became legible, and the change in how it felt to stand in front of it was total. The directory stopped being thirty-three people shouting. It became three active projects with my name on them, a quiet shelf of things that work, and a closed archive of things that are done. The same territory, finally charted, and the anxiety tax that I had been paying on every glance just stopped being collected.

This is the smallest, most concrete version of the only thing I really believe about complexity. You do not survive a sprawling domain by working harder inside the fog, and you do not survive it by pretending it is smaller than it is. You survive it by making it legible. Inventory what is there. Draw the edge. Decide, once and in advance, what counts as alive. That is a census, and a census is just a map, and a map is the difference between owning thirty-three things and being owned by them.

If you want the general method behind this, it is [the six layers](/2026/06/23/how-to-map-a-domain/). If you want the field it belongs to, it is [domain cartography](/domain-cartography/). This was just the day I pointed it at my own mess and watched the fog turn back into ground.]]></content:encoded>
      <pubDate>Tue, 23 Jun 2026 23:30:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/23/why-my-repos-needed-a-census/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/why-my-repos-needed-a-census.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>How to Map a Domain: The Six Layers</title>
      <link>https://joshuaayson.com/2026/06/23/how-to-map-a-domain/</link>
      <description>The hardest part of mapping a complex domain is the blank page. Here are the six layers I run every domain through, from primitives to levels, with the question each one answers, how to actually do it, and the failure mode that shows up when you skip it.</description>
      <content:encoded><![CDATA[The hardest part of mapping a complex domain is not the domain. It is the blank page.

You know the feeling. Something in front of you has grown too big to hold in your head, and you decide, finally, to draw it. You open an empty document. And then nothing happens, because there are a thousand true things you could write about this thing and no obvious reason to write one before another. So you either give up, or you produce a list that is really just the inside of your panic transcribed onto the screen, and the panic was the problem you were trying to solve.

The six layers are the cure for the blank page. They are the six questions I have learned to ask of any domain, in roughly this order, and they turn "map this impossible thing" into six small, answerable jobs. I wrote the field itself up separately, in [domain cartography](/domain-cartography/); this is the working manual for the method. None of these layers is clever. Run together, they are what turns an overwhelming pile into a map you can actually move with.

## Layer 1. Primitives: what is here?

Start by naming the pieces. The objects, the entities, the roles, the systems, the accounts, the people. Not what they do yet, not how they relate. Just an inventory of what is actually in the domain.

This sounds too simple to matter, and it is the step almost everyone skips, and skipping it is why so much complexity feels infinite. An un-inventoried domain has no floor. It feels like it could contain anything, because you have never made it say what it contains. The moment you write the list, the thing stops being a fog and becomes a countable set of parts. Thirty-one repositories, not "all my projects." Four accounts, not "my money." Almost always the real number is smaller than the dread.

How to do it: write the flat list, fast, without organizing. Do not stop to sort or judge. You are trying to hit the bottom of the pile, and the only way to know you have hit it is to keep going until you stop finding new things.

The failure mode: you confuse activity with inventory and never finish the list, so every later layer floats on top of a domain you only half-named.

## Layer 2. Forces: what moves it?

A list of parts is a still photograph. Forces are what make it a system. Ask what is pushing and pulling: the incentives, the constraints, the flows, the pressures, the things that pull effort toward some parts and away from others.

Every domain has a small number of forces that explain most of the motion. Money flows toward what already works. Attention has gravity, and the things that have it get more of it. Deadlines bend everything near them. If you can name the three or four real forces in a domain, you can usually predict where it will drift next without tracking every part, because the parts are not moving on their own. The forces are moving them.

How to do it: for each force, finish the sentence "this gets more of my time or money or attention because ___." If the answer is a real pressure, you have found a force. If the answer is "I am not sure," you have found a part of the domain you do not actually understand yet, which is also useful to know.

The failure mode: you map the parts and stop, and your map is a museum. It tells you what exists and nothing about what is about to happen.

## Layer 3. Boundaries: what is inside, and what is not?

Now draw the edge. What is in scope, what is deliberately out, where the seams and interfaces are, what you are choosing not to hold.

This is the layer that protects you, and it is the one people treat as optional. Choosing the boundary of a map is choosing what you are responsible for. Without it, the domain has no edge, which means it has no end, which means it expands to fill all the room you have and then keeps going. A boundary is not a confession of weakness. It is the thing that makes a map finite enough to read and a job small enough to finish.

How to do it: state out loud what is not on this map. "This map is my active work; archived projects are a different map." "This is my money this quarter; estate planning is elsewhere." The exclusions are as much a part of the map as the contents, and naming them is what makes the contents trustworthy.

The failure mode: no stated edge, so the map quietly grows until it is as overwhelming as the territory it was supposed to tame. A map the size of the world is not a map.

## Layer 4. Feedback: what loops?

Domains do not just sit there. They respond to themselves. Look for the cycles: the loops that reinforce and accelerate, the loops that balance and hold steady, and the slow drift you only notice looking back.

This is where the levers hide. The repository that gets attention because it works, and works because it gets attention, is a reinforcing loop, and if you want to change its trajectory you push on the loop, not the repo. The habit that funds the habit. The maintenance you defer that creates the fires that eat the time you needed for maintenance. Find the loops and you stop treating symptoms, because you can finally see the thing generating them.

How to do it: take any two parts and ask whether one feeds the other, and whether that comes back around. Trace it until it either closes into a loop or runs off the edge of your boundary. The closed ones are your real control surface.

The failure mode: you treat a loop as a one-time event, fix the symptom, and watch it regenerate, because the loop that produced it is still running untouched.

## Layer 5. Governance: who decides?

Even a personal domain has governance. Ask who or what holds authority here: the rules, the ownership, the escalation path, the answer to "when this is in conflict, who decides?"

When a domain feels chaotic, it is often not under-mapped. It is un-governed. There is no standing answer to who gets to decide, so every decision is relitigated from scratch, every time, under load. In a team this is obvious. In a personal domain it is sneakier, because the governor is you, and "you" is not one stable thing. You on a clear morning and you at midnight are different governors with different rules, and a domain with no governance defaults to whichever one is holding the pen at the worst moment.

How to do it: for the important parts, write the decision rule before you need it. "Archived repos do not get feature work, full stop." "No new position without bounded downside." Governance is just decisions made once, in advance, in calm, so they do not have to be made again in panic.

The failure mode: you map everything and govern nothing, so the map describes a domain that still runs on mood.

## Layer 6. Levels: what changes when you zoom?

The same domain looks like different things at different distances. Up close it is a taxonomy, a list of named parts. At mid-range it is relationships, parts wired to parts. From far away it is dynamics, the whole thing moving as one. A finished map can move between these altitudes without changing tools.

This matters because the answer you need usually lives at a different zoom than the question you asked. "Why does this keep breaking" is asked at the level of one part and answered at the level of the loop it sits in. "What should I even be working on" is asked at ground level and answered from altitude. A cartographer who is stuck on one zoom is reading a street sign and wondering why it will not tell them which country they are in.

How to do it: deliberately describe the domain three times, at three distances. One sentence from orbit, a paragraph from mid-range, the full inventory on the ground. If you can only do one of the three, that is the zoom you are trapped at, and the trap is worth knowing about.

The failure mode: single-altitude vision. Either lost in detail with no overview, or floating in abstraction with nothing concrete underneath it.

## How the layers compose

You do not always need all six, and you rarely run them cleanly in order. In practice you do a rough pass over primitives and boundaries just to get a floor and an edge, then the others pull on each other: naming a force reveals a loop, drawing a loop exposes a missing governance rule, governing a part makes you redraw the boundary. The list is not a pipeline. It is a checklist you circle back through until the map stops surprising you.

And two rules hold across all of them. Every map is provisional, because the territory moves and a chart you refuse to redraw becomes a lie you are loyal to. And every map is for action, because the test of a map is never how complete or beautiful it is. The test is whether, looking at it, you can see the next move. If you cannot, you have not made a map. You have made a picture of the problem.

If you want to see the six layers run on a real, messy domain instead of described in the abstract, I did exactly that to my own sprawl: [why thirty-three repositories needed a census](/2026/06/23/why-my-repos-needed-a-census/). That is the method with the mud still on it. This page is the manual. That one is the field.]]></content:encoded>
      <pubDate>Tue, 23 Jun 2026 22:30:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/23/how-to-map-a-domain/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/how-to-map-a-domain.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>Domain Cartography</title>
      <link>https://joshuaayson.com/2026/06/23/domain-cartography/</link>
      <description>Domain cartography is the practice of charting a complex domain you have to live and act inside, until it is legible enough to navigate. Not making it simple. Making it readable. Here is the field, the method, and the six layers every map needs.</description>
      <content:encoded><![CDATA[Every time something in my life got too big to hold in my head, I ended up drawing it.

Not literally, not always. Sometimes it was a table, sometimes a folder tree, sometimes a single page that just listed what was actually going on. But the move was always the same. The thing had grown past the point where I could keep it straight by remembering it, so I stopped trying to remember it and started trying to chart it.

I have thirty-three repositories under one organization, and at some point the only answer to "what is the state of all of this" was a map: which ones are alive, which are on life support, which are archived and just have not been told yet. My money has a map. My time has a map, broken into ten-day slices. The body of work this blog is made of has a literal generated [atlas](/atlas/). The pattern is so consistent that I finally stopped treating it as a quirk and started treating it as a craft.

The craft has a name now. I call it **domain cartography**.

## The field

Domain cartography is the practice of taking a complex domain and rendering it legible enough to navigate, decide, and learn inside, without pretending it is smaller than it is.

The key word is *domain*. Not a topic, not a dataset, not a diagram. A domain is a piece of the world you actually have to live and act inside: a codebase, a portfolio, a household, a career, a body, a company, a year. It has its own objects, its own forces, its own edges, its own ways of going wrong. And when it gets big enough, it stops fitting in one person's head, which is the moment most people quietly start drowning in it.

The cartographer's answer is not to shrink the domain. It is to draw it. To find the structure that is already there, under the noise, and make it visible enough that you can move on purpose instead of by reflex. A good map does not contain the territory. It contains the part of the territory you need in order to take the next step without walking off a cliff.

That is the whole discipline. Perceive the domain, find its real shape, render that shape, act from it, and redraw as the territory moves. It sounds modest. It is not. It is the only way I have found to act on something I cannot fully hold.

## Where it sits, and what it is not

I am not the first person to point a map at something abstract. It would be dishonest to pretend the space is empty, and the accurate version is more useful anyway, because it tells you exactly what domain cartography is by showing you what it is not.

**Knowledge cartography** is the closest named relative. It is a real academic field, built around visually mapping the structure of ideas and arguments: concept maps, argument maps, debate maps, tools for thinking and teaching. Its question is "how do these ideas relate?" Domain cartography borrows its tools freely, but its question is different. Not "how do these ideas relate" but "what is the state of this thing I am responsible for, and what do I do next." It is built for the operator, not the seminar.

**Domain analysis**, in software engineering, also maps a domain, but for a narrow purpose: finding the common and variable parts of a family of systems so you can reuse code. Same word, much smaller room. It is a technique that lives inside the larger practice, not the practice itself.

**Wardley mapping** charts a value chain against how evolved each piece is, and it is excellent at the thing it does, which is strategy. It is one map type, a specific instrument. Domain cartography is the workshop the instrument hangs in.

**Cynefin** is upstream of all of it. It tells you what kind of system you are standing in: clear, complicated, complex, or chaotic. That is a prerequisite, not a map. It tells you which terrain you are on. It does not chart the terrain.

So the lineage is real and I am glad to own it: systems thinking, cybernetics, complexity science, information architecture, knowledge management, the mapping traditions above. Domain cartography is not a rejection of any of them. It is the practitioner's craft that sits on top of them, aimed at a specific job none of them quite claims: charting the messy, living, personal domains you cannot opt out of, so a human can navigate them under load.

## The six layers

A map is only as good as what it chooses to show. Over and over, across very different domains, I keep reaching for the same six layers. They are the instrument set. You do not always need all six, but when a map feels useless, it is almost always because one of these is missing.

**Primitives. What is here?** The objects, the entities, the roles, the moving pieces. The repos, the accounts, the people, the systems. You cannot map a domain you have not inventoried, and most overwhelm is just an un-inventoried pile pretending to be infinite.

**Forces. What moves it?** The incentives, the constraints, the pressures, the flows. A list of objects is a still photograph. Forces are what make it a system. Money moves toward some things and away from others. Attention has gravity. Every domain has a few forces that explain most of the motion, and naming them is half the work.

**Boundaries. What is inside, and what is not?** The scope, the seams, the interfaces, the things you are deliberately not holding. This is the layer people skip, and skipping it is why they burn out. Choosing the edge of the map is choosing what you are responsible for. A boundary is not a limitation. It is the thing that makes a map finite enough to read.

**Feedback. What loops?** The cycles that reinforce, the cycles that balance, the slow drift you only notice in hindsight. Domains do not just sit there; they respond to themselves. The repo that gets attention because it works, and works because it gets attention. The habit that funds the habit. Find the loops and you find the levers.

**Governance. Who decides?** The authority, the rules, the ownership, the escalation path. Even a personal domain has governance, even if the only governor is you on a good day versus you at midnight. When a domain feels chaotic, it is often not under-mapped; it is un-governed, with no clear answer to who or what gets to decide.

**Levels. What changes when you zoom?** The same domain looks like taxonomy up close, relationships at mid-range, and dynamics from far away. A good cartographer can move between altitudes without switching tools, from the mission down to a single broken thing and back, because the answer you need lives at a different zoom than the question you asked.

Run a domain through those six and something happens that is hard to describe until you have felt it. The pile becomes a place. It stops being an undifferentiated weight and becomes terrain, with names and edges and routes. That is legibility, and legibility is the entire product.

## The map is for moving

Every map in this craft is provisional and every map is for action. Those two rules keep the maps true.

Provisional, because the territory moves and a map you refuse to redraw becomes a lie you are loyal to. The point was never one perfect chart. It is a living set of charts good enough to decide from this week, redrawn when the world has changed enough to earn it.

For action, because a map that does not change what you do next is decoration, and decoration is how mapping turns into procrastination wearing the costume of work. The test of a map is not how complete or beautiful it is. The test is whether, looking at it, you can see the next move. If you cannot, the map has failed, no matter how much of the territory it contains.

This is also where I have written about the failure mode from the inside: you cannot [simplify the ocean, only chart it](/making-complexity-visible/). The reduction reflex, the urge to crush a domain down to one number or one tidy diagram, fails the moment the thing it deleted turns out to be the thing that mattered. Cartography is the alternative to reduction. You keep the complexity and gain the legibility, which is the trade reduction promised and never delivers.

## The machine that finally made it possible

I have wanted to work this way my whole life. For most of it, I could not, because the limit was never the idea. The limit was memory. A human cartographer can only hold so much of the territory at once before the map starts decaying faster than they can draw it. Past a certain size, you spend all your effort just keeping the existing map from rotting, with nothing left to extend it.

That is the constraint that changed. Working [in agent mode](/2026/06/05/agent-mode-changes-the-shape-of-thought/), with a machine that can hold a far larger context than I can and never gets tired of the inventory, moves the ceiling. The repository census that used to be a week of dread is now a conversation. The first draft of a map, the boring pass over primitives and boundaries, is something I can delegate and then correct, which is exactly the right division: the machine extends my memory, I keep the judgment.

The real prize is not speed. It is coherence at a scale I could not previously sustain. The target is not a diagram or a dashboard or a product. It is a living orientation system: a map that holds many scales at once, knows what changed and when, is explicit about its own gaps, and is built for a human and a machine working the same chart together. That is the frontier I am actually pointed at, and domain cartography is the craft of building toward it by hand, one domain at a time, until the tooling catches up.

## Where it fits

Domain cartography is not a loose idea I am floating. It is one layer of a structure I have been building in the open for a while, and naming the layers is itself an act of cartography.

- [Making Complexity Visible](/making-complexity-visible/) is the **mission**: take the real state of a system out of one head or one black box and make it legible so anyone can see it.
- [Coherent Complexity](/coherent-complexity/) is the **philosophy**: complex and understandable are not opposites; you can map a system instead of reducing it.
- **Domain cartography** is the **field**: the actual [method and craft](/how-to-map-a-domain/) that does the mapping, with its own tools, layers, and standards.
- [Complexence](/complexence/) is the **capability**: the human quality of standing inside the domain, reading the chart under pressure, and still choosing.

Mission, philosophy, field, capability. The mission says why. The philosophy says it is possible. The field says how. The capability is the person who can actually do it when the domain is large and the stakes are real.

I keep drawing these maps because it is the only way I have found to stay coherent inside things that are genuinely too big for one mind. I do not make the world smaller. I chart the part of it I am standing in, well enough to take the next step, and then I redraw. That is the craft, and I think it is a real one, with a lot of map left to make.]]></content:encoded>
      <pubDate>Tue, 23 Jun 2026 21:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/23/domain-cartography/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/domain-cartography.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>Complexence</title>
      <link>https://joshuaayson.com/2026/06/17/complexence/</link>
      <description>Complexity is the condition of the world. Complexence is the quality you bring to it: the capability of standing inside a system larger than yourself, seeing it whole, and still choosing. A word for the thing all my work has been about.</description>
      <content:encoded><![CDATA[I have been writing about one thing for a year without a word for it. The essays look like they are about AWS, or agents, or DevOps, or attention, but those are the terrain I happen to be crossing. The thing underneath, the question I keep rediscovering in every domain, is how a person stands inside a system larger than themselves and does not come apart.

I finally have the word. **Complexence.**

## The word

Complexence is the human capability of orienting inside complexity without becoming emotionally fragmented. Seeing a system larger than yourself clearly enough to act, learning fast, holding direction while everything moves. The competence to stand in complexity and keep moving on purpose.

The ending is the whole point. Not *complexity*, which is the condition of the world, the thing in front of you, rising whether you like it or not. *Complexence*, which is the quality a person carries into it, the way we say competence, presence, patience. Complexity is what I am facing. Complexence is what I bring. One of those I do not control. The other is the only variable I ever really had.

You already know what it means before I define it. "She has tremendous complexence." You picture someone who handles uncertainty well, learns quickly, sees systems clearly, does not fracture under pressure, and adapts without losing the thread. That you can feel the word before you can define it is not a bug. It is why I am keeping it a little loose. The strongest words have room to grow.

## Reduction is the reflex that fails

Here is the premise I have made peace with. The world is getting more complex, not less, and it is not going to slow down for me or for you. Every reflex I inherited says the move is to make the complexity smaller. Reduce the system to one number. Reduce the market to one indicator. Reduce the body to one metric. Reduce the codebase to one tidy diagram everyone can agree on.

That move fails, reliably, and it fails in a specific way. It works right up until the moment the thing it deleted is the thing that mattered. The person who reduced the market to a single signal gets run over the first time the relationships shift, which they always do. The team that reduced the system to a clean diagram ships the diagram and then spends a year fighting the parts the diagram left out. The reduction was not wrong because it was incomplete. Every model is incomplete. It was wrong because it deleted the exact thing it claimed to explain.

I have written about this failure from the inside, about how you cannot [simplify the ocean, only chart it](/2026/06/02/making-complexity-visible/), and about what it looks like to make a system [legible without making it simple](/2026/06/02/coherent-complexity/). Complexence is the human end of that same idea. You do not survive growing complexity by shrinking it. You survive it by becoming the kind of person who can stand inside it, see it whole, and still choose. Not reduction. Orientation.

## The architecture

It took me a while to see that things I had been building separately were actually one stack. I thought there were three. There are five.

- **Making Complexity Visible** is the mission. The work of taking the thing that lives in one person's head, or inside one black box, and making its real state legible so anyone can see it.
- **Coherent Complexity** is the framework, the philosophy underneath the mission. The claim that complex and understandable are not opposites, that you can map a system instead of reducing it.
- **Complexence** is the capability. The human quality the mission and the framework exist to grow. The map can be on the wall and still do nothing. Complexence is the person who can read it under load and act.
- **Complexence OS** is the operating layer, the machine I built to run the capability as a daily practice, so the structure work happens outside my head. I wrote about that one [here](/2026/06/25/complexence-os/).
- **Complexence Labs** is the newest piece, added in July. The method stopped being something you read and became something a project can install, and every project that installs it becomes a laboratory: it measures whether orientation actually improved and what it cost, and only sanitized patterns ever travel back to the public repo, never the work itself. The runtime is grammar. The labs are knowledge. That move gets its own essay.
- And underneath all of it there was a floor I did not expect. Complexence is not only something a person does. It is something you can study. A field, with a formal shape, the way quantity has mathematics and truth has logic and computation has computer science. There is a science of orienting inside complexity, and I have been going down into it lately. It gets its own essay.

The work makes complexity visible so that coherence is possible so that complexence can develop, and now there is a machine that runs it, a science that grounds it, and laboratories that measure it. That stack has been the spine of everything I make. I only just found the top and the bottom of it.

All of it is open, the capability map, the method, the science, and now an installable runtime and the live research questions, in one place: [the Complexence repository on GitHub](https://github.com/OrganicArtsLLC/complexence). The repository opens with what is unsolved, on purpose.

## The loop under everything

When I line up the concepts I keep returning to, the ones that feel most like mine, they are all asking a single question wearing different clothes. [AWS is math and Kubernetes is physics](/2026/05/31/aws-is-math-kubernetes-is-physics/). Agent mode changes the shape of thought. Rhetoric is the [physics of other minds](/2026/06/17/rhetoric-is-the-physics-of-other-minds/). Making complexity visible. Each one is really asking: how does a person perceive, simplify, navigate, and govern a system larger than themselves?

Underneath all of them is the same loop:

```
Perception → Maps → Orientation → Decision → Action → Feedback → Learning → (back to Perception)
```

That loop runs in engineering, in leadership, in parenting, in investing, in a hard conversation, in a ten-day reflection cycle. Complexence is the name for being good at that loop, all the way around, on a system you cannot fully hold. The body of work is just field notes from running it in one domain after another.

When I finally went looking for what that loop actually is, underneath the plain words, it did not stay a metaphor. It is a recursive equation. A thing that observes, remembers, predicts, decides, acts, and folds the result back into the next turn, and then does it again. The capability is that loop run well, under load, by a person. The science is what *well* means precisely. That is the floor I mentioned, and it is the whole of the next essay. And as of July the measuring has begun: every project I run is now a small laboratory reporting one thing, did orientation improve, and what did it cost.

## The better map

I spent real time chasing a narrower version of this question: what is the actual best map of modern complexity? The answer was clarifying. The better map is not a diagram, a dashboard, or a product. A good map of a living system has to answer four questions at the same time. *What exists? What is happening? What changed? What should we do next?* Most tools answer one or two of those and quietly fail at the rest.

So the better map is less a picture and more a living orientation system: multi-scale, so you can move from mission down to a single incident without changing tools; temporal, so it shows what changed and when, not just what is; open about its own freshness and gaps, so trust is earned instead of assumed; built for human and machine together, with the AI summarizing and proposing and the human keeping the final judgment; and coupled to action, so it ends in a decision and not just a feeling of having understood.

That is the external version of complexence, the one you could build in software. The internal version is the same properties running in a person. Hold scale. Track change. Know what you actually know. Work with the machine without surrendering to it. And never stop at understanding when the point was to move.

## It is built, not issued

The most important thing about complexence is that it is a capability, which means it is trained. Nobody is born with it and nobody downloads it. I did not have it at twenty, drowning in a room where everyone seemed faster. I have more of it now, and all of the gain came from the same unglamorous moves, run until they became reflex.

Build the map outside your head, because memory cannot hold the whole and was never meant to. Take controlled exposure, standing in steadily more complexity without fleeing, the way you build any capacity, which is also the [antifragile move](/2026/05/30/living-with-antifragility/) pointed at your own nervous system. Train the pause, because the flood comes from believing you must respond the instant the complexity arrives, and you must not. Close the loops you open, because the learning is the half everyone skips and it is where the capability compounds. And protect the friction that is teaching you, even while you hand the pure drudgery to a machine, because [not all friction is waste](/2026/06/17/compressed-or-destroyed/) and some of it is the only thing that ever built the instinct.

None of it is fast. It is slow accumulation that cannot be bought in a hurry, the residue of years of standing in things that were one size too big and refusing to come apart.

## The stance

I have given up the fantasy that I will make the world simple. So this is what complexence comes down to, the whole thing in one breath.

I do not reduce the ocean. I learn to read it, and I keep moving.

Stand inside the full size of the thing. See it whole. Do not fragment, do not flatten, do not freeze. Orient, decide, act, and close the loop. That is how I am learning to stand in this growing complexity, and it is the answer to the only question that was ever really mine to answer. Not how to make the world smaller. How to become someone large enough to hold it.

*Postscript, July 2026: a few weeks after I wrote this, I found the man who spent eighty years on the same question. [Finding Edgar Morin](/2026/07/12/finding-edgar-morin/).*]]></content:encoded>
      <pubDate>Wed, 17 Jun 2026 21:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/17/complexence/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/complexence.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>Compressed or Destroyed</title>
      <link>https://joshuaayson.com/2026/06/17/compressed-or-destroyed/</link>
      <description>The same tool that can fold a beginner&apos;s learning curve shorter can also erase it. AI compresses apprenticeship when it transfers expertise and destroys it when it lets people skip the repetitions that were quietly teaching them.</description>
      <content:encoded><![CDATA[The same mechanism that makes AI a great teacher is the one that makes it a great way to stop learning. It depends entirely on what the learner does with the time the tool gives back, and the two outcomes look identical for about a year before they stop looking identical at all.

Start with the good version, because the evidence for it is strong. In the big study of customer support agents, access to an AI assistant raised productivity about fourteen percent on average, and about thirty-four percent for the newest and least experienced workers, with almost no gain for the veterans. The likely mechanism, the authors suggest, was that the tool [captured the habits of the best agents and handed them to the beginners](https://www.nber.org/papers/w31161), moving new people down the experience curve faster than the job ever could on its own. That is apprenticeship compressed. The thing a good mentor does, transferring hard-won judgment to someone who has not earned it yet, done at scale and on demand. It is one of the most genuinely hopeful findings in all of this.

Now the other version of the same mechanism. If a beginner uses the tool to produce good work without ever doing the messy, unglamorous part themselves, they get the output of expertise without the formation of it. And the formation was never in the output. It was in the mess.

## What the mess was for

Everyone who got good at something difficult got good through repetitions that felt like a waste of time while they were happening. The hours of debugging that slowly built an instinct for where bugs live. The bad first drafts that taught taste by being bad in instructive ways. The architecture you got wrong and had to live with, which is the only thing that ever teaches you to smell a wrong one early. None of that was efficient. All of it was the training, and it was disguised as drudgery the entire time.

A 2025 paper makes the structural case for taking this seriously, arguing that [AI deskilling is not a personal failing but a property of the environment](https://doi.org/10.1007/s00146-025-02686-z). When a system reliably does the work a person used to do, it can create what the authors call a capacity-hostile environment, one that erodes the very abilities that work used to develop, not because anyone chose to deskill but because the repetitions simply stopped happening. The danger is not that people get lazy. It is that the gym closes and nobody notices until they need the muscle.

Which means the hard managerial fact buried in all of this is that not all friction is waste. Some friction is training. This is the antifragile idea pointed at a person: [Taleb's case that some things gain from disorder](/2025/12/29/antifragile-things-that-gain-from-disorder-by-nassim-nicholas-taleb/), that stress and difficulty are inputs a system needs and not just damage to remove. I have [tried to build my own life and systems to work that way](/2026/05/30/living-with-antifragility/), and the same logic holds for a skill. Take away every stressor and the worker does not get stronger. They get more fragile. A company that strips out every inefficient repetition in the name of speed can save an enormous amount of time while hollowing out the pipeline that was supposed to produce its next generation of senior people. The repetitions a junior should keep are exactly the ones a spreadsheet would flag for elimination first, because from the outside developmental friction and pure waste look the same. Telling them apart is real work, and almost nobody is doing it on purpose.

## The floor is rising

You can already see the shape this pushes careers into. When AI absorbs the bottom rungs of a job, the typing and the boilerplate and the basic lookup, the rungs do not get replaced with easier ones. They get replaced with harder ones. PwC's barometer is picking this up: AI-exposed entry-level jobs are increasingly asking for the senior, human-intensive skills, judgment and leadership and synthesis, earlier than people used to have to supply them. Other work on job postings finds the same shift, with [demand rising for higher-order cognitive and social skills](https://arxiv.org/abs/2503.09212) rather than the mechanical ones the tools now cover.

So the value of typing, boilerplate, generic summarizing, and mechanical translation between formats is falling, and the value of framing, taste, review, synthesis, domain judgment, and teaching is rising. The human either moves up into that work or gets hollowed out underneath it. The cruelty is in the timing. We are asking people to start their careers at an altitude that used to take a decade to reach, while removing the gentle lower slopes that used to get them there. The floor of the profession is rising, which is good for the work and brutal for whoever was standing on the old floor expecting to climb the normal way.

## What I actually do about it

My own view has limits here. I do run a company, but it is a tiny LLC, not the kind of place with a talent pipeline to measure or a bench of juniors to deskill, so the organizational version of this is something I have read about more than lived at that scale. At my size the picture nearly inverts. I do not have to worry about scaling. I pay for exactly one person's cognitive amplification, my own, I know precisely what it costs and how it gets used because I am the one using it, and I point it at every part of the business. For my own business that makes it very cheap labor and a very low cognitive cost, a no-brainer, and in most cases a write-off besides.

I happen to see the other end of it too. Inside a large employer I can only imagine the same bill looks enormous and the return genuinely questionable, which is the paradox at the heart of the whole problem. Same technology, opposite verdict. The only things that changed are the scale and the hidden ledgers that come with it: the coordination tax, the talent pipeline, the meetings that never get shorter. None of those reach a business of one, which is probably why I can see them so clearly from here. I am not drowning in them.

What I can speak to firsthand, then, is my own skills, where the deskilling risk is the same mechanism, just smaller.

The accumulated feel I rely on, the thing that lets me sense [where an agent is reliable and where I have to take the wheel](/2026/06/17/the-jagged-frontier/), is nothing but the residue of years of doing the work the hard way before the tools existed, the kind of thing that [compounds across a career](/2026/05/27/devops-beyond-automation/) and cannot be bought in a hurry. I did not download that. I cannot download more of it. And I have noticed that if I let the agent do a certain kind of thinking for long enough, the part of me that used to do it gets quieter, the way any unused thing does. So I keep some of it deliberately. I still do certain things by hand, not because the tool cannot, but because the doing is keeping a capacity alive that I am not willing to lose. The move I called thinking alone in the work is partly this: a refusal to offload the things that are still teaching me something.

That is the whole discipline, scaled up or down. Decide which repetitions are pure waste and let the machine have them, gladly. Decide which repetitions are secretly the training and protect them, even when keeping them costs you the very efficiency the tool was supposed to deliver. Get that judgment wrong in the cheap direction and you save time now and pay for it later in capability you no longer have. This is the slowest and least visible of [the four ledgers in the real bill for AI](/2026/06/17/the-real-bill-for-ai-at-work/), the one with no monthly invoice and the longest tail. Compressed or destroyed is not a property of the tool. It is a choice about which mess you decide to keep.]]></content:encoded>
      <pubDate>Wed, 17 Jun 2026 19:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/17/compressed-or-destroyed/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/compressed-or-destroyed.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>Botsitting</title>
      <link>https://joshuaayson.com/2026/06/17/botsitting/</link>
      <description>The subscription is the small line. The real meter is the time you spend feeding context, checking output, catching the confident mistake, and cleaning up the work that looked finished. That hidden labor has a name now: botsitting.</description>
      <content:encoded><![CDATA[There is a kind of work that does not feel like work and does not show up anywhere, and most of my time with AI is spent on it. Deciding what to ask. Loading enough context that the answer has a chance of being good. Reading the output closely enough to trust it. Catching the place where it went confidently wrong and steering it back. Doing the whole loop again because the first result was almost right, which is the most expensive kind of result there is. It feels like producing. It is mostly supervising.

The workplace researchers have started naming this, which is how you know it is real and not just my temperament. Glean's index of digital workers found people spending around six hours a week "botsitting," feeding and correcting and babysitting their AI tools, more time than they spent using those tools to produce the actual work. Six hours. That is most of a working day, every week, going into a column that no budget has and no dashboard tracks. The subscription is the line item everyone debates. The botsitting is the bill.

## The attention tax

I have written before about [the part of my own mind the agents took over](/2026/06/16/the-patient-part/), the long flat middle of a task that a machine is glad to grind through. That part is real and it is a gift. But it came with a tax, and the tax is attention. Every hour the tool saves me on the doing, it bills back some fraction on the deciding and the checking, and that fraction is invisible because it does not look like effort. It looks like reading. It looks like thinking. It is the cost of being the one responsible for output you did not personally produce.

The dangerous thing about this tax is that you cannot feel it from the inside, because the felt experience of using AI lies to you in a specific direction. A 2026 study found what the authors called a speedup illusion: people expected the tool to make them much faster and reported lower effort using it, even on tasks where it saved no time at all. Less strain is genuine and worth something. But less strain is not more output, and a tool that feels like a shortcut while costing you the same hour is the easiest expense in the world to undercount. I have trained myself to distrust the feeling of speed and look only at what actually shipped, because the feeling and the shipping have come apart, and the feeling is the louder of the two.

There is a second move buried in the attention tax that almost nobody counts: deciding when not to use the tool at all. That decision is itself work. Every task now carries a small upfront question, is this inside the frontier or just outside it, is this faster delegated or faster done by hand, and answering it costs a little attention before any work happens. Multiply that micro-decision across a day and it adds up to a real load, the cognitive overhead of running a second worker who is fast, tireless, and occasionally, fluently wrong. I have argued before that [attention is the scarce resource](/2026/01/28/on-threads/), the thing to spend on purpose. Botsitting is what happens when a tool spends it for you without asking.

## The coordination tax

The attention tax is the part I pay myself. The coordination tax is the part the system pays, and it is larger, and it falls on other people.

Here is the pattern the field experiments keep finding. AI makes you faster at the parts of your job you can change alone: the writing, the summarizing, the first draft, the search. In one randomized study across dozens of firms, the clearest effect was that people spent meaningfully less time on email. But the same study found the broader shape of work mostly unchanged, because [the rest of the job runs on coordination](https://arxiv.org/abs/2504.11436), and coordination did not get faster. Meetings did not shrink. Approvals did not speed up. Handoffs and ownership and the review bottleneck all sat exactly where they were. The individual got faster. The system did not, because the system was never limited by how fast any one person could draft.

And then there is the version where the local speedup makes the system slower. Stanford and BetterUp gave it a name that is hard to forget: [workslop](https://hbr.org/2025/09/ai-generated-workslop-is-destroying-productivity), polished AI output with nothing underneath it, passed to a colleague who then spends real time discovering it is hollow and redoing the work. Around forty percent of desk workers reported receiving some in a single month, costing roughly two hours each to sort out. Look at the arithmetic of one incident. The sender saved ten minutes generating a clean-looking draft. The receiver lost two hours. The company is down an hour and fifty minutes and it shows up as productivity, because the sender's ten-minute win is the only part that got measured. The cost moved downstream, out of sight of the person who created it, which is exactly why the behavior keeps repeating. I have written about [owning the word slop](/2026/01/30/i-am-ai-slop/) and what separates craft from waste in machine-made work. Workslop is that waste, dressed up to look finished and handed to someone else to find out it is not.

This is the real reason the individual can feel transformed while the organization stays flat. The gains are local and the costs are distributed. One person banks the time saved. Another person, somewhere down the chain, pays it back with interest, and no ledger connects the two.

## What the bill actually says

So when someone reduces the cost of AI to the subscription plus the tokens, they are reading the cheapest line and ignoring the meter. The full bill looks more like this:

subscription, plus context preparation, plus verification, plus rework, plus the cleanup of work that looked finished, plus the trust you have to rebuild every time the confident output turns out to be wrong.

None of that is an argument against the tools. I would not give them up, and the time they save me on the doing is real even after the tax. It is an argument for counting where the money goes, because you cannot manage a cost you refuse to name. The financial line is the one the finance team can see. The attention and coordination lines are the ones that decide whether you actually came out ahead, and they are the ones [the real bill for AI](/2026/06/17/the-real-bill-for-ai-at-work/) is mostly made of. Count them, or keep wondering why the productivity you can feel so clearly never shows up in the numbers.]]></content:encoded>
      <pubDate>Wed, 17 Jun 2026 18:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/17/botsitting/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/botsitting.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>Rhetoric Is the Physics of Other Minds</title>
      <link>https://joshuaayson.com/2026/06/17/rhetoric-is-the-physics-of-other-minds/</link>
      <description>If AWS is math and Kubernetes is physics, then discourse is the physics of other minds, the same live, empirical, pushes-back system, except the matter is a person and the latency is a blank stare. Why the studio and the arena are two different rooms, why the second one floods you, and how to build the faculty that levels the field.</description>
      <content:encoded><![CDATA[There are two rooms where language happens, and you are not the same person in both.

The first is the studio. Alone, on the page, composing. Here you have all the time in the world. You take a thought and abstract it into an idea, classify it, build the structure, revise until it is clean. One direction, on your terms, no clock. This room you own.

The second is the arena. Live, two minds, the clock running, the demand to answer *now*. Another person's thought arrives faster than you can file it, and while you are still parsing the first claim the second is already on top of you. It floods. And the strange, maddening thing is that it is the *same faculty*, the same ability to turn thought into language, running in a mode you were never trained for. The studio proves the skill is there. The arena proves you have only ever used half of it.

I have spent most of my life strong in the first room and underwater in the second. For a long time I read that as a verdict, some people are quick on their feet and some are not. I no longer believe it. The overwhelm is not a statement about intelligence. It is an untrained reflex, and reflexes are the most trainable thing there is.

## Language is almost everything

Start with what is actually at stake, because it is larger than winning arguments.

Language is the most powerful abstraction of thought we have. It is how we describe, classify, enlist, influence, and operate. It is the layer we lay over raw reality so that two separate minds can hold the same thing at once. Strip it away and there is no plan, no agreement, no persuasion, no shared anything, just two animals near each other, guessing. Almost everything human runs on this one abstraction.

Trevor Noah tells the cleanest version of this in [*Born a Crime*](/2026/06/21/born-a-crime-trevor-noah/). A kid in apartheid South Africa, he learned the tongue of whatever group surrounded him, and in one scene a mugging simply dissolves, he answers his would-be muggers in their own language and *target* becomes *one of us*. Nothing changed but the words. The threat didn't shrink; the field leveled. That is the whole thesis in a single street corner. You cannot always win on status, volume, or credentials. You can win on precision, meeting a mind where it stands and being understood before you can be dismissed. Rhetoric is the landscape that levels the field, and language is how you stand on it.

## The physics of other minds

I have been describing the systems I build the same way for a while now. AWS is math: the galaxy, structure seen from far enough away that it resolves to clean arithmetic, and you watch the cost. Kubernetes is physics: the atom, live matter that pushes back with latency and heat, and you watch the performance. Two ends of one spectrum, the certain and the real.

Discourse is the third point on that line, and it belongs to the physics end. **Rhetoric is the physics of other minds.** Same live, empirical, pushes-back system, except the matter is a person and the latency is a blank stare. You cannot read your way to it any more than you can read your way to a running cluster. Feynman's line holds here too: *what I cannot create I do not understand.* Except the thing you create is understanding inside another head, in real time, and that head tells you instantly whether you managed it, a counterexample, a subject change, a jaw setting hard. It does not send you a grade. It sends you the next move. You watch the performance. Always.

Picture the exchange as a small physical system. Two charged bodies, each holding a state, beliefs, mood, what they want. Between them, a medium: language, the field that carries force from one to the other, lossily. Most of what we call disagreement is just noise in that field, the same word naming two different things, not a real clash of states. There is pressure, the live demand to respond, which is exactly what the studio lacks and the arena always has. There is a current, the direction the conversation wants to flow. And there is turbulence: too much arriving too fast to parse, which is the overwhelm, felt from the inside.

Here is the move that changes everything once you see it. You never command another mind. You *declare* a claim into the field and watch the other body move toward it, or fail to, and then close the gap with your next word. It is a reconciliation loop, the same restoring force a Kubernetes controller runs, forever comparing desired state to actual and nudging the difference closed, except the desired state is a shared understanding and the feedback is a human face. The craft is refusing to pretend you have been understood until the other body actually shows it.

## The floor is composure

You cannot listen while you are flooded, and you cannot steer while you are swept. So the first thing to build is not a clever line. It is a self that stays online under pressure.

The Stoics handed us the tool two thousand years ago. In any exchange, sort fast into two bins. Not yours: their tone, their move, whether they are fair, whether they will concede. Yours: your judgment about what just happened, your next word, your pace. The flood almost always comes from treating their move as something happening *to* you that you must instantly fix. Epictetus saw it exactly: it is not things that disturb us, but our judgments about things. Reframe the incoming as data you get to process at your own pace, and half the turbulence drops on the spot.

Out of that comes the single highest-value habit in the whole craft, and it is almost embarrassingly simple: the pause. The arena's worst lie is that you must answer the instant the other person stops talking. You must not. Two seconds of chosen silence reads as gravity, not weakness. The people who seem fastest in a room are usually the ones most comfortable being quiet in it. Hesitation only looks weak when it *leaks*: the um, the eyes going up, the voice rising. A pause you take on purpose reads as command. The leak and the choice look identical to a stopwatch and opposite to a human being.

## Reception is a skill, not a talent

Then the part I was sure I simply lacked: listening, while a fast mind sprawls at me.

I drowned because I tried to hold everything at once, their claim, my three rebuttals, the side-point, the thing they said a minute ago, my own rising pulse. Six live threads into a working memory that holds about three, and the system overflows into static. The fix is structural, and it is the whole game: hold one thread, theirs, until it is complete, then answer one piece of it. You do not have to answer everything. You almost never should. Find the beam the rest is resting on and engage *that*; the scaffolding falls when the beam goes.

And the move that does the most work is the one usually taught as mere fairness: the steelman. State the other person's view at its strongest, in a form they would endorse, *before* you answer it. Re-read that as a listening instrument and it transforms. You cannot strengthen what you only half-heard, so it forces real reception. It buys the pause inside a sentence that *raises* your standing instead of stalling. And it changes the current, a person who has just been understood, better than they said it themselves, stops pushing and starts listening back. "So the strongest version of what you're saying is this, and the best reason for it is this. Have I got it right?" is the most disarming sentence I know, and it is pure reception.

After that the kit is small and ancient: name the missing warrant, the silent premise an argument leans on. Relocate the stasis when two people are fighting hard at different questions, fact, definition, value, policy. Pin the loaded term before you argue about it, because half of all heat is two people using one word for two things. Concede precisely, out loud, on the points that are actually right, because fast concession on a real point is the mark of the strong, not the beaten. None of it is loud. All of it is one level more precise than the room.

## Step into the arena

I had a professor at the University of Washington, S. Marc Cohen, who taught the practical reasoning course I took in 1995, and who made all of this look like nothing. He was not faster than the room, and he was not louder. He was composed, he listened better than anyone in it, and he was always one notch more precise than whoever he was talking to, so the field was level on his terms, every time. The class was hard, harder than it had any right to be for something with reasoning in the title, and I did not understand why until years later, when I found his [lecture notes still posted online](https://faculty.washington.edu/smcohen/120/LectureNotes.htm) and read them as an adult. Underneath the practical course was real machinery: first-order logic, the careful work of separating a claim from its form, the discipline of saying exactly what follows from exactly what and nothing more. That rigor is the floor this whole essay stands on, and I did not pour it. He did, into a room of undergraduates who mostly did not know what they were being handed.

I want to name him, because I have stopped believing in self-made anything. [Every map I draw now](/2026/06/02/making-complexity-visible/), every attempt to [make a complex domain legible instead of merely simple](/2026/06/02/coherent-complexity/), runs on reasoning that teachers like him built into me in rooms I did not appreciate at the time. I honor all of them, the instructors and professors who taught me to decode long before I knew I would spend my life decoding, who handed me the tools I am only now learning to name. For years I filed Professor Cohen's ease under *gift*. I think now it was a craft, drilled, and that the drilling is available to anyone willing to treat the arena as a place you train rather than a place you survive.

Math proves; physics tests. The studio composes; the arena answers. You write the clean version alone, and then you ship the shadow into a live exchange and find out which parts were ever real. Both rooms are the job. The whole thing only works when you stop pretending either one is the entire truth.

The flood, it turns out, is not the other mind being large. It is laminar flow lost, structure you have not yet learned to read. Learn to read it and the same fast, charged, sprawling mind stops registering as turbulence and starts registering as what it always was: structure arriving, one thread at a time, that you have the moves to meet.

The field is open. Step into the arena. Let's go.

---

## Related reading

- [AWS Is Math, Kubernetes Is Physics: A Symphony of Systems](/2026/05/31/aws-is-math-kubernetes-is-physics/), the galaxy and the atom, and the spectrum this essay extends to a third point
- Sources for the ideas borrowed here: Trevor Noah on language and survival (*Born a Crime*, 2016); Epictetus and the Stoics on the dichotomy of control (*Enchiridion*); Aristotle on the three appeals and the enthymeme (*Rhetoric*); Cicero and Hermagoras on stasis theory; Richard Feynman on creating in order to understand (*The Character of Physical Law*, 1965).
- The reasoning backbone is formal logic. Professor S. Marc Cohen's [logic lecture notes](https://faculty.washington.edu/smcohen/120/LectureNotes.htm) at the University of Washington, grounded in *Language, Proof and Logic* by Jon Barwise and John Etchemendy ([2nd edition](https://www.gradegrinder.net/Products/lpl-index.html)), the text and its Tarski's World software, are where I first learned to separate a claim from its form.]]></content:encoded>
      <pubDate>Wed, 17 Jun 2026 17:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/17/rhetoric-is-the-physics-of-other-minds/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/rhetoric-is-the-physics-of-other-minds.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>The Jagged Frontier</title>
      <link>https://joshuaayson.com/2026/06/17/the-jagged-frontier/</link>
      <description>AI is strong in one place and confidently wrong half a step over, and from the inside the two feel identical. The real skill is not prompting. It is knowing when to delegate, when to steer, when to verify, and when to think alone.</description>
      <content:encoded><![CDATA[An agent has never once told me it was guessing. It hands me the wrong answer in the same voice it uses for the right one, formatted just as cleanly, sounding just as sure. That single fact is the reason working with these tools is a skill and not just a convenience. If the failures announced themselves, anyone could use AI well. They do not announce themselves. They arrive wearing the same face as the wins.

The research has a precise name for the shape of the problem. When BCG's consultants used a frontier model on tasks inside its range, they finished about a quarter faster and produced better work. On a task built to sit just outside that range, the same tool made them roughly nineteen percent more likely to get the answer wrong, because it was every bit as fluent on the problem it could not actually do. Dell'Acqua and his coauthors called the boundary a [jagged technological frontier](https://d3.harvard.edu/navigating-the-jagged-technological-frontier/), and the word is exact. It is not a clean line with easy on one side and hard on the other. It is jagged. The tool is brilliant at something genuinely difficult and broken at something that looks adjacent and simpler, and the two sit right next to each other with no marker between them.

So the actual skill, the one that decides whether AI helps you or quietly costs you, is reading that boundary in real time. I have written about [what working at that edge feels like day to day](/2026/06/08/working-at-the-frontier/); this is the mechanism underneath the feeling. I have come to think of it as four moves, and most of working with agents is choosing the right one for the task in front of me.

## Delegate, steer, verify, think alone

**Delegate** is for the deep interior of the frontier. The task is well inside what the tool does reliably, the stakes are low, and I can check the result in seconds. Renaming across a codebase, drafting boilerplate, translating a config from one format to another. I hand it off completely and barely look back. This is where the speed everyone talks about actually lives.

**Steer** is for inside the frontier but near its texture, where the tool can do the work but not unattended. I stay in the loop, read as it goes, correct course early and often. This is the line I have drawn between [agent mode and autonomous mode](/2026/06/12/agent-mode-vs-autonomous-mode/): the difference is who closes the loop, me or the machine, and near the edge of the frontier it has to be me. Most of my real building is here. It is not hands-off and it is not me typing every character. It is a conversation where I supply the direction and the judgment and the agent supplies the speed and the patience.

**Verify** is the move people skip, and skipping it is where the bill comes due. The tool produced something plausible, but plausible is not the same as correct, and I cannot trust it on this particular task without checking it against something real: a test, a source, a second pass from a different angle. The output looking right is not evidence. It always looks right. That is the whole danger.

**Think alone** is the one that is easy to forget you still have. Some tasks are outside the frontier, where the tool will be confidently wrong and I am better off without it. And some tasks are inside it but I should still do them myself, because the thinking is the point. Closing the tool is a legitimate move, not a failure of nerve. The hard part is that from the inside, the task you should hand off and the task you should sit with alone can feel exactly the same.

## Why it is hard from the inside

The reason this takes judgment and not a checklist is that the two signals you would naturally use are decoupled. Fluency is constant. Competence is jagged. The model writes with the same easy authority whether it is right or wrong, so the confidence in the output tells you nothing about the correctness of it. Every instinct you have for reading a human, where hesitation and hedging and a careful tone usually track real uncertainty, points you the wrong way.

That decoupling has a name in the literature too. [Automation bias](https://link.springer.com/article/10.1007/s00146-025-02422-7) is the tendency to over-rely on an automated recommendation precisely when it looks fluent and authoritative, and a 2025 review traces it through medicine, law, and public administration, anywhere a confident machine answer meets a tired human. The fix the researchers settle on is not "trust the AI" and not "be skeptical of the AI." Both of those are too blunt to use. The goal is trust calibration, matching your reliance to the tool's actual capability on this specific task. Appropriate reliance is the entire game, and it has to be recomputed every time, because the frontier is jagged and the task just changed.

## Building the fence around the edge

Because I cannot hold all of that in my head on every task, I do not try. I build the judgment into the system instead of leaning on my own attention to supply it fresh each time.

The most useful thing I do is keep an adversarial second agent whose only job is to attack the first one's work, to try to refute it rather than admire it. A model is good at finding holes in output when you point it at the output and tell it to be hostile, and it does not get tired or invested the way I do. I [run my code review this way](/2026/06/11/ai-code-review-workflow/) on purpose: review the change, not the typing, and assume the confident draft is hiding something until a second pass proves it is not. I build gates that close the loops I would otherwise leave open, tests that have to pass, checks that have to clear, so that the verify move is not relying on me remembering to make it.

The other half is knowing my own domain's edges, which is the part that does not transfer and cannot be downloaded. [Working as a senior engineer with these tools](/2026/06/12/how-i-use-ai-as-a-senior-engineer/), I can feel where the agent is reliable and where I have to take the wheel, and that feel is just the accumulated memory of every place it has burned me before. It is the most valuable thing I own in this work, and a junior cannot have it yet, which is its own problem and the subject of its own essay.

## The frontier moves

One more thing keeps this from ever becoming a fixed rule. The frontier moves. Every model release redraws the line, usually outward, sometimes in strange local ways, and a task that was outside the boundary last quarter is comfortably inside it now. So the boundary is not something you learn once and file away. It is something you keep testing, deliberately, by handing the tool things at the edge of what you think it can do and watching where it breaks. The people who decided two years ago what AI was bad at and stopped checking are now wrong in both directions, trusting it where it has gotten dangerous and avoiding it where it has gotten good.

This is why I never have a clean answer when someone asks whether AI is overhyped. The question assumes a fixed answer to a moving target. The answer is that it is extraordinary inside the frontier and a liability just outside it, and the only durable skill is the one that tells the two apart on a specific task, today, with this model. That skill is not prompting. Prompting is the cheap part, the part a cheat sheet can teach. This is judgment under uncertainty, and it is the thing that decides how heavy [the real bill for AI](/2026/06/17/the-real-bill-for-ai-at-work/) turns out to be. Guess the frontier right and the tool extends you. Guess it wrong and you have just paid full price to be confidently misled.]]></content:encoded>
      <pubDate>Wed, 17 Jun 2026 17:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/17/the-jagged-frontier/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/the-jagged-frontier.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>The Real Bill for AI at Work</title>
      <link>https://joshuaayson.com/2026/06/17/the-real-bill-for-ai-at-work/</link>
      <description>The invoice for AI is the cheap part: a seat and some tokens. The real bill arrives in four ledgers: financial, attention, coordination, and development. Why AI makes the individual feel fast while the organization barely moves.</description>
      <content:encoded><![CDATA[The invoice is the cheap part. A seat, some tokens, a line item the finance team can read in a second. I work with agents every day, and the number on that invoice has almost nothing to do with what the tools actually cost. The real bill arrives somewhere else, in a currency nobody puts on a purchase order.

You can feel the gap if you have lived inside it, and I have, [running a single agent across more than thirty of my own repositories](/2026/06/13/ai-agents-across-many-repositories/). The tool makes you faster on the thing in front of you, immediately and obviously, and you walk away sure the whole system just got faster too. It usually did not. This is the most consistent finding in the workplace research, and it is strange enough to sit with: in Glean's survey of digital workers, about three quarters said AI makes them more productive, and only about one in eight said their organization was performing significantly better as a result. Denmark ran the cleaner test, linking adoption surveys to actual payroll and hours across thousands of workplaces, and in the first couple of years found no meaningful effect on wages or hours at all. Fast individual, flat organization. The same shape keeps coming back.

That gap is not a mystery once you stop looking at the invoice and start counting what the invoice leaves out. I have come to think of AI cost as four ledgers, not one. Three of them never show up in the budget, and they are where the money actually goes.

## The four ledgers

**Financial** is the visible one. Seats, tokens, infrastructure, the security review, the integration work, the vendor contract. This is the cost everyone argues about and the only one most companies actually track. It is also, in my experience, the least interesting, because cheap tokens do not mean cheap adoption. The economists who study general-purpose technologies have a name for the trap: the [modern productivity paradox](https://www.nber.org/papers/w24001), where the spending and the reorganizing come now and the visible gains come much later, if you do the reorganizing at all. The expensive part of AI was never the model. It is everything you have to rebuild around it. At my own one-person scale there is almost nothing to rebuild, which is exactly why the tool stays cheap for me. At the scale of a large organization, the rebuild is most of the bill.

**Attention** is the first hidden one, and it is the one I pay myself, every day. It is the cost of deciding what to ask, loading enough context for the answer to be any good, reading the output closely enough to trust it, catching the place where it went confidently wrong, and steering it back. Glean's index put a number on this that matched my own week uncomfortably well: workers reported spending around six hours a week ["botsitting,"](/2026/06/17/botsitting/) feeding and checking and correcting the tools, more time than they spent using the tools to produce the actual work. None of that shows up anywhere. It feels like working. It is mostly supervising.

The dangerous part of the attention ledger is that it is easy to miss from the inside, because the felt experience lies to you. A 2026 study found what the authors called a speedup illusion: people expected AI to make them much faster, and reported less effort using it, even on tasks where it did not actually save any time. Less strain is real and worth something. But less strain is not the same as more output, and a tool that feels like a shortcut while quietly costing you the same hour is the easiest expense in the world to under-count. I have learned to distrust the feeling of speed and look at what actually shipped.

**Coordination** is the second hidden ledger, and it is the one that eats the gains. AI makes you faster at the parts of your job you can change by yourself: the writing, the summarizing, the first draft, the lookup. It does almost nothing for the parts that need other people: the approval, the handoff, the unclear ownership, the review that is already a bottleneck. So the local speedup is real and the system speedup is not, because the work still has to pass through all the same human gates it did before.

Worse, the local speedup can make the system slower. Stanford and BetterUp gave the failure mode a good name, [workslop](https://hbr.org/2025/09/ai-generated-workslop-is-destroying-productivity): polished, low-substance AI output that gets passed to a colleague who then has to spend real time figuring out it is hollow and redoing it. Around forty percent of desk workers reported receiving some in the prior month, costing roughly two hours each to resolve. The person who generated it saved ten minutes. The person downstream paid two hours. That cost is invisible to the one who created it, which is exactly why it keeps happening. One person's productivity win is another person's tax, and the tax is larger than the win.

**Development** is the slowest ledger and the one I worry about most for the people coming up behind me. It is the cost of what the work used to teach. The clearest evidence that AI can teach is also the clearest warning that it can stop teaching: in the big call-center study, AI raised productivity about fourteen percent on average and about thirty-four percent for novices, apparently by transferring the habits of the best workers to the newest ones. That is the good version, compressed apprenticeship, the experience curve folded shorter. But there is a [destroyed version of the same mechanism](/2026/06/17/compressed-or-destroyed/). If a junior uses AI to skip past the messy, unglamorous repetitions, they also skip the thing those repetitions were building under the surface: the taste, the debugging instinct, the sense of when an architecture is wrong before you can say why. A 2025 paper makes the structural case that this is real, that systems which replace valuable human activity can erode the very capacities that activity used to develop.

Which means not all friction is waste. Some friction is training, and a company that strips out every repetition in the name of efficiency can save a great deal of time while hollowing out its own talent pipeline. PwC's barometer is already picking up the shift: AI-exposed entry-level jobs are now far more likely to demand the senior, human-intensive skills, judgment and leadership, earlier than people used to have to supply them. The floor of the career is rising. That is good for the work and brutal for whoever is standing on the old floor.

## The skill that runs through all four

There is one skill that decides how heavy each of those ledgers gets, and it is not prompting. It is knowing where the tool is good and where it is quietly bad.

The research has a sharp picture of this. When BCG's consultants used a frontier model on tasks inside its range, they did better and finished about a quarter faster. On a task built to sit just outside that range, the same tool made them roughly nineteen percent more likely to get the answer wrong, because it was just as fluent and confident on the problem it could not actually do. The authors called the boundary a [jagged frontier](https://d3.harvard.edu/navigating-the-jagged-technological-frontier/), and the word is right. It is not a clean line between hard and easy. It is jagged, strong in one place and subtly broken half a step over, and from the inside the two feel identical.

So the real skill is [judgment under uncertainty](/2026/06/17/the-jagged-frontier/): knowing when to delegate, when to steer, when to verify, and when to close the tool and think alone. I do this constantly, mostly without noticing, and the days it goes well are the days I correctly guessed which side of the frontier I was on. The cognitive scientists frame the underlying move as value-based: we offload a piece of thinking when it feels effortful or low-value, weighing the cost of doing it ourselves against the cost of checking what the machine did. Good offloading frees you for higher work. Bad offloading weakens a muscle you still need. Telling them apart, in the moment, on a specific task, is the whole job now.

## What the four ledgers are for

I keep coming back to a frame I have written about before, which is that most of the work of getting anything right is [making the real state of a system visible](/2026/06/02/making-complexity-visible/) so nobody has to go hunting for it. The four ledgers are that move pointed at AI cost. The reason companies buy AI and cannot find the return is not that the return is fake. It is that they are reading one ledger and getting billed on four. The gains are real and local. The costs are real and spread across attention, coordination, and development, where no dashboard is looking.

None of this is an argument to use less AI. I use more of it every year, and it has changed [how the work actually feels](/2026/06/16/the-patient-part/). It is an argument to stop treating AI as a cheap answer engine and start treating it as a cognitive prosthetic, something that can genuinely extend you and can also, used badly, weaken the body around it. A prosthetic is worth a great deal. It is also not free in the way a subscription is free once you have paid for it.

The mature version of the question is not how much AI your people should use. It is which parts of human thinking you want to make cheaper, which parts you want to protect, and which parts you want to grow. The companies that win will not be the ones that buy the most. They will be the ones that redesign the work while keeping alive the human capacities that made the work worth doing in the first place. That decision does not live on the invoice. It never did.]]></content:encoded>
      <pubDate>Wed, 17 Jun 2026 16:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/17/the-real-bill-for-ai-at-work/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/the-real-bill-for-ai-at-work.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>The Patient Part</title>
      <link>https://joshuaayson.com/2026/06/16/the-patient-part/</link>
      <description>My head does not run in a line, it runs in branches. A tool arrived that does the exact part I cannot do and amplifies the exact part I already do too much. On building with an agent when your attention has its own ideas.</description>
      <content:encoded><![CDATA[My head does not run in a line. It runs in branches. I will be doing one thing and three more will arrive uninvited, fully formed, each one sure it should be started right now, and the thing I was actually doing quietly loses its color. I have started more projects than I will ever finish. I have a folder of them. I have a folder of folders.

For most of my life this was just a fact about me, and the rooms I worked in were built for a steadier kind of attention than the one I have. The ideas were never the problem. The ideas came for free, more than I could ever use. The problem was the long flat middle of any single one, the stretch with the novelty burned off, where you have to sit and do the next unglamorous step forty times without flinching. That part and I have never gotten along. My attention is a strong current that goes where it wants, and the middle of a project is slack water.

Then I started building with an agent in the room, and something I did not expect happened. The tool fit.

Not the usual way, where you sand yourself down to match the tool. This one bent toward the way my head already worked. I could think out loud at it, jump, contradict myself, chase the branch that just walked in, and it held the thread I had dropped. When the current moved, it kept the place I left. The long flat middle, the forty steps with no shine on them, turned out to be exactly the part a machine is glad to do while I am off somewhere with the next idea. I bring the surges. It brings the patience. I once wrote about what it feels like to run [many threads at once at machine speed](/2025/07/22/the-multithreaded-mind-six-weeks-living-at-machine-speed/); this is that, one floor down, where it stops being a productivity story and gets personal.

There is a quieter piece too. The feedback is fast. You say a thing and a minute later the thing exists, and that small hit of a result right now is enough to keep me in the chair through a stretch that used to be unsurvivable. I am not white-knuckling the boring part anymore. The boring part got handed off, and what is left is the work I was always built for, the seeing and the deciding and the next jump. Over enough months it has even [changed the shape of the thinking itself](/2026/06/05/agent-mode-changes-the-shape-of-thought/).

There is another edge, and it is sharp. The same machine that keeps up with me is the most efficient way I have ever found to start forty things and finish none of them. It will chase every branch with me, equally delighted by all of them. It never gets tired, never says we already have three of these, never once asks whether the bright new thing is actually better than the half-built thing I walked away from an hour ago. A novelty engine pointed at a mind that runs on novelty is a gorgeous way to spend a year and have nothing to show for it. I know, because I have done it, and I can still feel the pull on a good day, the tool happily helping me scatter myself across the table.

So the thing I have actually had to learn is not how to prompt. It is how to build the fence. The agent is the engine, and the discipline has to come from somewhere outside my own head, because my head is far better at starting things than at keeping them. So I put the plan where I can see it. I make the state [legible to me on a page](/making-complexity-visible/) instead of leaning on a memory I have never been able to trust to hold one. I keep a second agent whose only job is to finish what I started and to ask, out loud, whether the new idea is really worth more than the open one. I build gates that close the loops I would otherwise leave hanging forever. None of this is about the model, and none of it is about fixing me. It is scaffolding, and I worked it out the slow way, by failing at it for years and watching exactly how I failed. It is the same move I have been making my whole life. Not to become someone steadier. To work with what is actually there, and get more out of it than the steadier version of me ever could.

So when someone asks me whether these tools are overhyped, I never have a clean answer, because the question is more personal for me than it is for them. A tool showed up that does the exact part my attention will not sit still for and amplifies the exact part I already do too much. It is the best thing that has happened to the way I work and a loaded gun aimed at it, and which one it turns out to be on any given day comes down entirely to whether I built the fence before I picked up the engine.]]></content:encoded>
      <pubDate>Tue, 16 Jun 2026 16:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/16/the-patient-part/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/the-patient-part.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>AWS Is Smaller Than It Looks</title>
      <link>https://joshuaayson.com/2026/06/15/aws-is-smaller-than-it-looks/</link>
      <description>AWS is taught as two hundred services. Underneath it is a handful of primitives, and every service is a frozen answer to a distributed-systems trade-off. The map I built studying for the SAA-C03, and the two questions that decode any new AWS service.</description>
      <content:encoded><![CDATA[AWS looks enormous because it is sold that way. Two hundred services, each with its own name and logo and console, and underneath them the quiet implication that you are meant to learn them one at a time, forever. I have come to think that is mostly an illusion. The catalog is enormous on purpose, because catalogs sell, but under it there are maybe seven ideas. Once you can see them, AWS stops being a library you memorize and becomes a small set of shapes you recognize.

I did not get there by reading a summary. I got there the slow way, studying for the Solutions Architect exam until the services stopped looking like separate things. Transit Gateway is a router. AppSync is a front door with a filter on it. The names kept changing and the shapes underneath kept repeating, and at some point the catalog stopped growing, not because I had memorized it but because I had stopped meeting anything genuinely new.

## The first time the catalog folds

Pick any handful of services and ask what each one actually does, stripped of the name.

| The service | What it actually is |
|---|---|
| Route table | a decision table |
| Security group | a filter |
| IAM policy | a filter that happens to be about permission |
| ALB | a thing that hands work to whichever worker is free |
| NAT gateway | an address translator |
| CloudFront | a cache |
| SQS | a queue |
| EventBridge | a router for events |

None of those are AWS inventions. A queue is a queue. A cache is a cache. A filter is one of the oldest ideas in computing. AWS did not invent them. It packaged them, gave each one a console and a price, and sold it as a distinct product. Once you can see the queue inside SQS, SQS stops being something to memorize and becomes something you already understand.

## Everything is one of five verbs

Go one level lower and even the archetypes rhyme. Almost every service in AWS is doing one of five things to information. It stores it. It moves it. It transforms it. It protects it. Or it watches it.

- **Store:** S3, EBS, DynamoDB, RDS
- **Move:** Route 53, the load balancers, the gateways, the route tables
- **Transform:** Lambda, ECS, the analytics services
- **Protect:** IAM, KMS, security groups, the policy layers
- **Watch:** CloudWatch, X-Ray, CloudTrail

That is the whole platform in five words. When you are lost in a new service, the fastest way back to solid ground is to ask which of the five it is doing, because the verb tells you what questions to bring. A service that stores has storage problems: durability, cost, access. A service that moves has movement problems: latency, routing, what happens when a hop fails. Name the verb and you already know half of what to worry about.

## Below the verbs, it is just math

Keep going and the verbs dissolve too. A VPC is not really a network, it is a graph. A route table is a function over the edges of that graph. A security group is a set of constraints. A load balancer is a distribution algorithm wearing a hostname.

I wrote a whole piece about this feeling, that [AWS is math](/2026/05/31/aws-is-math-kubernetes-is-physics/) the way a galaxy is math: vast, composable, provable, and billed by the hour. The archetypes are the middle of a ladder. Look up and you see products. Look down and you see graphs, flows, constraints, transformations, and state. Same platform, read at different altitudes.

## What the whole thing is for

There is one more way to fold it, and it is the one I reach for most at the console. AWS is a navigation system. Almost every service exists to answer one of four questions.

- **Where is it?** Route 53, service discovery, DNS.
- **How do I get there?** Route tables, the gateways, the load balancers.
- **Am I allowed?** IAM, security groups, NACLs, service control policies.
- **What happened?** CloudWatch, X-Ray, CloudTrail.

Find where it is, find the path to it, check that you are allowed down that path, and keep a record of what happened. That is most of cloud architecture, described without a single product name.

## The seven

When I flatten all of it, the same small set keeps falling out. Identity. Boundaries. Routing. Storage. Computation. Messaging. Observation. Seven primitives. AWS ships dozens of new services a year, and almost every one is a fresh arrangement of those seven, or an old arrangement with better defaults.

## The level below the primitives

There is one floor below the primitives, and it is the one that turns recognition into judgment.

A primitive tells you what a service is. It does not tell you why there are three of them. AWS gives you more than one key-value store, more than one way to replicate, more than one queue, and the differences between them are not features. They are trade-offs that someone already made and froze into a product.

DynamoDB and an Aurora global database are both, at the primitive level, just storage. But Dynamo leans toward availability: it hands you single-digit-millisecond reads at scale and eventual consistency by default, and charges you in latency and cost when you demand a strong read. Aurora Global leans the other way, holding consistency and paying for it in replication latency. Same primitive, opposite answers to the same old question, which is the trade-off between consistency, availability, and the latency you are willing to tolerate. Every storage service in the catalog is a position on that spectrum.

And it is a small set of axes, not an endless list. Under a network partition you get consistency or availability and never both, which is the CAP theorem, and every multi-node store in AWS is a frozen answer to it. Even when nothing is partitioned you are still choosing, because a strong read has to be coordinated and coordination costs latency. That is the full version of the rule, PACELC, and it is why a strongly consistent DynamoDB read costs you roughly double and an Aurora global write has to wait on the far Region. Availability has its own ladder, the nines, and each extra nine is exponentially harder to hold, so "highly available" is a budget decision before it is a technical one. Durability comes down to two numbers, how much data you can afford to lose and how long you can afford to be down, your recovery point and recovery time, and those two pick a disaster-recovery design before you have named a single service. That is most of the trade-off space. Learn those few axes and the storage menu, the database menu, and the replication options stop being lists to memorize and become positions you can place by eye.

This is the part a certification cannot hand you directly, because it gives you the answers without ever showing you the questions. A service is a frozen answer to a trade-off. Once you can see the trade-off, the menu stops being a list to memorize and becomes a set of choices with reasons attached. "Strongly consistent, multi-Region, willing to wait" stops being a keyword to match and becomes a sentence you could have finished yourself.

## The patterns are the next size up

Above the single service there is one more layer that repeats, and it is the one that actually shows up when you sit down to design something real. A handful of named patterns get reached for again and again, and AWS ships a managed box for almost every one.

When work arrives faster than you can handle it, you put a queue in front and drain it at your own pace. That is load leveling, and it is SQS. When one event has to reach many consumers that do not know about each other, you fan it out through a topic. That is publish and subscribe, and it is SNS or EventBridge. When a downstream dependency starts failing, you stop hammering it and fail fast until it recovers, instead of letting the failure climb back up the stack. That is a circuit breaker. When a transaction has to span services that cannot share a single database commit, you break it into local steps, each with an action that undoes it, and you orchestrate the sequence. That is a saga, and it is Step Functions. When reads and writes have nothing in common in shape or scale, you split them into separate models. That is CQRS. When you are migrating off something old and cannot afford a rewrite, you put a router in front and peel capabilities off one at a time until the old thing is dead. That is the strangler fig, and it is an API gateway sending old paths to new code.

None of these are AWS inventions either. They are the standard moves of distributed systems, written down long before the cloud existed, and AWS mostly packaged each one and put a price on it. Once the dozen patterns are in your head, a system design stops being a blank page. It becomes a question of which moves to assemble and in what order, and the services are just where you reach to assemble them.

## The question that shrinks it

Here is the practical payoff, and it is the only study trick in this whole piece.

When a new service drops, do not ask what it is. Ask which primitive it is repackaging, and then the harder question underneath that one: which trade-off did it freeze.

Those two substitutions are the difference between learning AWS forever and reading it on sight. A service announcement that would have been an afternoon of docs becomes a sentence. That is a queue with ordering guarantees. That is IAM with a nicer grammar. That is a cache with a CDN bolted to the front. That is the consistency knob turned one notch toward availability. You are not learning a new thing, you are recognizing an old one in a new coat.

## Why I trust this map

I did not theorize these layers. They fell out of the grind. I run a small loop when I study: push the knowledge into a real scenario, catch exactly where I stumble, distill the stumble into one card, and drill it until it is automatic. Six weeks of running AWS through that loop and the catalog collapsed into archetypes on its own. The map is just the residue of the friction.

And it is the same move I keep making everywhere. I built a [live map of my own blog](/atlas/) so a few hundred posts would stop being a pile and start being a structure. I wrote a [field guide to sound](/the-language-of-sound/) so the thing I could feel but not name would finally hand me its vocabulary. This is the AWS version of the same instinct: a domain stops being a black box the moment you give it a map and a small vocabulary.

So it is not really about AWS. It is about [making complexity legible](/making-complexity-visible/) instead of memorizing it. Find the primitives. Name the verbs. Spot the pattern it implements. Ask which trade-off each service froze, and which old idea the new name is hiding. The biggest platform in the world has a surprisingly small number of moving parts, once you stop reading the labels and start reading the shapes.]]></content:encoded>
      <pubDate>Mon, 15 Jun 2026 17:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/15/aws-is-smaller-than-it-looks/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/aws-is-smaller-than-it-looks.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>The Language of Sound: A Field Guide for Making Music</title>
      <link>https://joshuaayson.com/2026/06/14/the-language-of-sound/</link>
      <description>I could already make sound. I could not name it, and you cannot ask for a thing you cannot name. So I asked my music engine for a map. This is that map: sound built in altitudes, and the words that let you climb it.</description>
      <content:encoded><![CDATA[I have always been moved by sound. Not as a hobby I picked up later, but as
something closer to the center of me. A chord change can reorganize a room. A low
end you feel in your chest is a different animal from one you only hear. I love
the way music makes me feel, and for a long time that love sat on one side of a
wall. I could feel sound completely. I could not make it.

Then I built ChipForge, my music engine, and the wall moved. ChipForge makes
every instrument from code. No samples, no recordings, just numbers between
negative one and positive one, forty four thousand of them a second, sent to a
speaker as vibration. Every effect is arithmetic on that list of numbers. That is
the demystifying truth I keep coming back to: it is all math on a list of numbers,
and I can already make it produce sound.

So capability was never the thing stopping me. The thing stopping me was that I
could not name what I was hearing. When something sounded amateur I had no word
for which part was wrong, and you cannot ask for a thing you cannot name, cannot
notice when it is off, cannot tell where its edge is. The pros are not smarter
about sound. They have words for it, and the words are hooks that let you pull one
thing at a time out of a wall of noise. I wrote a whole essay recently, [Working at the Frontier](/2026/06/08/working-at-the-frontier/), arguing
that the real limit on thought is language, the narrow channel cognition has to
pass through to become anything you can share. Sound turned out to be the same
problem wearing different clothes, and the same lesson runs through [Making Complexity Visible](/making-complexity-visible/): a hard thing stops being a black box once you can name its parts.

So I asked ChipForge for a map. Not more features, a vocabulary. A field guide
written for my own engine, every word tied to a real knob in the code and to a
sentence I could actually say out loud. What came back is the most useful thing I
have read about music in years, and it is the thing I want to give you here.

## Sound is built in altitudes

Here is the whole model, and once you see it you cannot unsee it. Everything in
this engine, and in all of music production, stacks in altitudes:

```
  Altitude 5 :: THE MASTER       the whole song as one finished object
  Altitude 4 :: THE MIX          how the parts sit together: space, balance, width
  Altitude 3 :: THE ARRANGEMENT  what notes, when, in what role
  Altitude 2 :: THE INSTRUMENT   the character of one voice
  Altitude 1 :: THE NOTE         one sound from start to finish
  Altitude 0 :: THE PHYSICS      what sound actually is
        ↓
       your ear, the feeling
```

A signal flows up. A note is shaped into an instrument, instruments are arranged,
the arrangement is mixed, the mix is mastered. But when you diagnose a problem you
go down. "This feels harsh" is a feeling. "The highs are too loud" is a guess at
altitude four. "The lead's filter is too open up at the top" is the actual cause,
down at altitude two, where you can reach in and fix it.

That is the entire skill in one sentence. Every problem, mud, harshness, the
vague sense that something sounds cheap, lives at exactly one altitude, and you
fix it there. Learning to ask "which altitude is this?" is most of the game. The
words below are organized that way, climbing from the physics up to the finished
record.

## Altitude 0: the physics

Four properties, and everything else is a combination of them. Frequency is how
fast the air vibrates, and doubling it moves you up one octave. Amplitude is how
big the vibration, the loudness, measured in decibels. Timbre is the color of a
sound, the reason a flute and a saw playing the same pitch are instantly
different, and it comes from harmonics, the quiet higher tones stacked above the
fundamental. Get those four and you have the alphabet. There is nothing to build
down here, only to learn, because the engine already speaks physics fluently.

## Altitude 1: the note

A single note has a shape in pitch, which is the waveform, and a shape in time,
which is the envelope, and then it gets sculpted by a filter. Those three are the
holy trinity of synthesis, the foundation under nearly every synth sound ever
made.

The waveform is the raw color. A sine is pure and hollow, a tuning fork with no
overtones. A sawtooth is buzzy and full, all the harmonics at once, the rasp under
a trumpet or a screaming lead. A square is woody and retro, the Game Boy tone.
Noise is hiss and wind, the raw material of every cymbal and snare.

The envelope is the most important idea for making something sound played instead
of generated, and it has four letters, ADSR. Attack is how fast the note reaches
full volume; fast is a pluck, slow is a swell. Decay is how it settles. Sustain is
the level it holds while you keep the key down. Release is the tail, how long it
rings after you let go. The single most common beginner mistake, said in this
language, is notes that are too short. Real notes breathe.

The filter is where most of the magic hides. A low pass filter lets the lows
through and removes the highs above a cutoff point, and lowering that cutoff is
the one knob for "make it warmer" or "make it less harsh." Put an envelope on the
cutoff itself and the brightness moves over the life of the note: the swell of a
bowed string, the blat on the front of a brass stab. That moving filter is the
single biggest jump in realism that most beginners skip entirely.

## Altitude 2: the instrument

An instrument is a waveform plus an envelope plus a filter, plus the thing that
makes it rich, which is layers. Real sounds are never one oscillator. A piano is a
hammer click on top of a string body on top of a sub. Stack two to four slightly
detuned voices and the tone gets a body and stops sounding thin.

The best trick I learned here is how to talk about a timbre at all: describe it as
material plus action plus size. A struck glass. A bowed, swelling string. A
plucked, decaying wire. A breathy, hollow tube. That is how producers brief each
other, and it maps cleanly onto the engine, because material is the waveform,
action is the envelope and the filter, and size is the layers and the register.
Once you can say "a struck glass," you can build a struck glass.

## Altitude 3: the arrangement

This is where the conversation stops being about physics and starts being about
music. Which notes, in what order, played by which part of the band. The home note
is the key, the note everything wants to return to. A chord is notes stacked, a
progression is chords in sequence, and tension and resolution is the engine under
all of it: dissonance wants to move, consonance is home, and withholding the
resolution is exactly how a track stays brooding instead of letting you off the
hook.

Then there are roles. Kick, snare, and hat are the rhythm section. Bass is the
foundation. The pad is the warm floor. The lead is the voice, the hook. The real
arrangement skill is not adding, it is knowing what to leave out, managing the
density so every part has room. This is also where my engine has its own edge,
because an algorithm can make every single bar unique instead of copying and
pasting, and a machine can try a thousand variations of a groove before you pick
one. That advantage is the whole reason I built the thing from scratch.

## Altitude 4: the mix

If the arrangement is what, the mix is where. A great mix has depth, width, and
clarity, which means you can hear every part and each one sits in its own place.
Pan moves a sound left or right. Reverb pushes it front to back, near or far. EQ
balances the tone, cutting the frequencies that are fighting. Compression tames
the loud parts so the quiet parts survive.

The idea that organized all of this for me is frequency real estate. Every sound
wants its own band. Sub bass owns the very bottom, the body sits in the low mids,
presence is the band where melody and vocals cut through, and there is a narrow,
painful band up high where too much energy makes your ears hurt. Mud is too many
sounds crowding the low mids. Harsh is too much in that painful band. Thin is
missing body. Those three words diagnose almost every bad mix I have ever made,
and now I can say which one it is.

## Altitude 5: the master

Mastering is the final polish on the whole song summed into one stereo file,
making it loud and cohesive without breaking it. Limiting is a brick wall the
signal cannot cross, so you get volume without clipping. Glue compression makes
the separate parts feel like one performance instead of a pile of tracks.

But the real lesson of the top altitude is not a tool, it is a habit. Measure, do
not guess. My engine prints five numbers about any finished track: how loud it
peaks, its average energy, how much dynamic punch survives, how wide it is, and
where its tonal center sits. Reading those numbers turns "it sounds bad" into
something specific I can act on. That one habit, measuring instead of guessing, is
the fastest way to stop sounding like a beginner.

## Name the altitude, fix it there

Here is how the whole map pays off in practice. Something sounds wrong. Instead of
flailing at random knobs, you name the feeling, the feeling gives you the word,
and the word points at the altitude and the fix.

Boxy and blurry means muddy, which is too much energy in the low mids at altitude
four, so you cut the low mids and thin the arrangement. Painful highs means harsh,
so you tame that narrow upper band. Small and weak means thin, so you layer the
voice and add weight underneath. Flat and robotic means it was never humanized, a
problem up at the arrangement, so you let the timing and the velocities breathe.
Wrong, off notes are almost never a synthesis problem, they are a key problem at
altitude three, notes that wandered outside the scale.

That table, feeling to word to fix, is the thing I actually wanted all along. Not
a bigger engine. A way to hear precisely, and to say what I hear.

## Why this matters to me

This is a map, not a manual, and it is going to keep growing. Every time a session
turns up a useful word I add it to the field guide, so the thing stays alive
instead of going stale. I am publishing it because I suspect a lot of people are
where I was: able to feel sound all the way down, blocked only by not having the
words for it.

The music this engine makes is real and out in the world now. You can hear it on
my [music page](/music/), the Napkin Films soundtracks and the Plan 9 volumes, all
of it rendered from pure math by ChipForge. Why I build my own engines instead of
reaching for someone else's is its own essay, [Why I Build Creative Technology](/2026/05/30/why-i-build-creative-technology/).
And I am now walking each altitude on
its own, in video, with the real audio drawing itself on the screen as it plays.
That series is The Language of Sound, the first episode is live, and the details
are at the end of this map.

I spent years on the wrong side of a wall, loving sound and unable to make it. It
turned out the wall was made of missing words. Once I had the map, the engine I
had already built stopped being a black box and became an instrument I could
finally play.

## Watch the series

I am turning this map into a film series, the same idea walked one altitude at a
time, except now you can see it. No teacher on camera. Everything on the screen is
driven by the real audio, a live oscilloscope tracing each waveform as the Governor
names it. Season One is six episodes, from a single note up to the machine writing
music on its own, and the first two are live.

The full series, with every episode and how it is made, lives at [The Language of Sound](/2026/06/14/the-language-of-sound-series/). Or jump straight to the [playlist on YouTube](https://www.youtube.com/playlist?list=PLYsRDF0ixYudxZSi2pOLRK-vjFu2b8Ip4). It sits alongside the rest of the studio at [Napkin Films](/films/).]]></content:encoded>
      <pubDate>Sun, 14 Jun 2026 16:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/14/the-language-of-sound/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/the-language-of-sound.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>Directing AI Agents Across Thirty-Three Repositories</title>
      <link>https://joshuaayson.com/2026/06/13/ai-agents-across-many-repositories/</link>
      <description>There are thirty-three repositories in my workspace, and I cannot hold more than two of them in my head at once.

They sit side by side in one folder, but it is not a monorepo. Each is its own indepen...</description>
      <content:encoded><![CDATA[There are thirty-three repositories in my workspace, and I cannot hold more than two of them in my head at once.

They sit side by side in one folder, but it is not a monorepo. Each is its own independent project with its own stack, its own history, its own conventions. A blog built in Astro. Film tooling in Python. A chiptune engine. A few daily-practice command-line tools. Infrastructure. They share an owner and almost nothing else. The Python repo and the Flutter repo would not recognize each other's rules.

The naive way to point an agent at this is to give it the whole workspace and hope. It does not work, and the reason it does not work is instructive.

## One big context is the wrong shape

An agent turned loose on all thirty-three repos inherits the union of every project's conventions and belongs to none of them. It writes Python with the Node repo's instincts. It uses the wrong deploy script because two of them are named almost the same. It reaches for a path that was real in one project and stale in another. More context did not make it smarter. It made it average across projects that should never be averaged.

The fix is the opposite of more context. It is a boundary, one per repository.

## The instruction file is the unit of work

Each repo carries its own instruction file. It says what this project is, what the stack is, what the conventions are, what is dead, and what bites. The agent reads that file first, and inside that repo it behaves like it has worked there for months. It knows this one uses a virtual environment in one folder and that one uses a different folder. It knows which deploy needs which flag. It knows the gotcha that took me a day to find the first time, because I wrote the gotcha down.

Move to the next repo and the agent reads a different file and becomes a different specialist. The workspace root holds almost nothing, just the cross-cutting scripts that manage remotes and sync, and a single note at the top that says, before you touch anything, go into the specific repo and read its file first.

So the orchestration is not one large mind holding everything. It is routing. The right work, scoped to the right repo, carrying that repo's instruction file as its working memory. Breadth stops being expensive the moment each stream brings its own context with it. I can have a migration running in one repo, a bug in another, and a draft in a third, each scoped so it cannot bleed into the others.

## The files are the memory I do not have

Those instruction files are the externalized version of the context I genuinely cannot hold. I do not remember which of thirty-three repos puts its virtual environment where, which path went stale in a refactor last spring, which script still points at an old directory. I am not going to pretend I do. The file remembers so I do not have to.

That changes what being wrong about a repo means. When I get one wrong, the fix is not to try to remember harder next time. It is to write the correction into that repo's file, so neither I nor the next agent makes the same mistake again. The files are a system, and like every system I run they leak, so I keep refactoring them, often by pointing an agent at a repo and asking it where its own instructions have drifted out of date with the code. That review is some of the highest-leverage work I do, and it is never finished, because the repos keep moving.

I should also say plainly that this is not the best way to do this. It is the best way I have found so far, which is a different thing. There are better methods than mine right now, some I have not learned yet and some that do not exist yet, and the meta question of how to work is never closed for long. The instruction-file approach is a stage I am passing through, the way cursor completion was a stage before it. You grow into a method and then you outgrow it, and the next one is usually already there when you do. Anything I write down about how I work is a photograph of a stage and not a destination, and the part I am most sure of is that next year I will be doing it differently.

The whole thing comes down to one idea. Multi-repo agent work is not a scale problem, it is a context problem, and the unit is not the agent, it is the boundary you draw around what it should know. Draw the boundaries well and you can work across thirty-three projects without holding thirty-three projects. Draw them badly and the agent is confidently wrong in a different way in every folder. The rest of how I work this way lives at [AI-assisted engineering](/ai-development/).]]></content:encoded>
      <pubDate>Sun, 14 Jun 2026 05:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/13/ai-agents-across-many-repositories/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/ai-agents-across-many-repositories.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>Putting a Password on a Static Site With One CloudFront Function</title>
      <link>https://joshuaayson.com/2026/06/13/password-protect-cloudfront-static-site/</link>
      <description>A static site has no server to check a password, which is fine right up until the day you need one.

My staging site is the problem in miniature. It is a full mirror of production, except it also carr...</description>
      <content:encoded><![CDATA[A static site has no server to check a password, which is fine right up until the day you need one.

My staging site is the problem in miniature. It is a full mirror of production, except it also carries every unpublished draft, so it must not be public. But it is the same kind of thing production is, a pile of files in an S3 bucket served through CloudFront, with no application server anywhere in the picture. There is no request handler to put a login in front of. The files just sit there and CloudFront hands them out.

So you have to check the password somewhere that does exist, and on a static site that place is the edge.

## The right tool is smaller than you think

CloudFront has two ways to run your code on a request, and the difference matters a lot here.

A CloudFront Function is a tiny piece of JavaScript that runs at every edge location, on the request, before the cache. It is deliberately limited. It cannot make network calls or run for long. It exists to look at a request and make a fast yes-or-no decision, which is exactly the shape of checking a password. It runs in well under a millisecond and costs almost nothing.

Lambda@Edge is the heavier cousin. A real runtime, more time, the ability to talk to other services. It can do far more, and for gating a static site that is the problem, not the appeal. Reaching for Lambda@Edge to check one header is bringing a server to a job whose whole point was that there is no server.

The gate is a CloudFront Function. It reads the Authorization header, checks it against the expected credential for HTTP Basic Auth, and either returns a 401 that makes the browser ask for a password or lets the request through to the files. That is the entire job.

## Keep the password out of the repository

The credential is not in the function. That matters, because the function is code and code goes in git, and a password in git is a password you have published whether you meant to or not.

So the password lives in a secret store on my machine, and it gets injected into the function only at deploy time. The version in the repository has a placeholder where the secret goes. The deploy fills it in, ships it, and the real value never touches version control. If you take one thing from this, take that one: the edge function and the secret it checks should never live in the same place.

## The edge is unforgiving

Here is the part I learned the hard way. A mistake in a normal request handler breaks one request. A mistake at the edge breaks the site, because the edge is the thing every request passes through before anything else runs.

I had an older, abandoned attempt at this gate sitting in the repo, written as Lambda@Edge from before I understood that a Function was the right tool. The dead code looked enough like the live code to be dangerous, and one day it got deployed instead of the Function. Staging did not ask for a password. It returned 503 to everyone, a locked door with the lock jammed.

Two habits came out of that. The deploy now validates the function on a development stage and only publishes to live once it passes, because an auth function that fails does not fail open into an annoyance, it fails closed into an outage. And the dead Lambda@Edge file is now a loud tombstone that says, at the top, do not deploy this, here is the one that is real. Future-me does not get to rediscover the 503 by hand.

That is the whole lesson, and it generalizes past staging gates. A static site can do far more at the edge than its lack of a server suggests, but the edge punishes mistakes at the scale of the whole site rather than the single request, so you validate before you publish and you keep exactly one living version of anything that runs there. The rest of how I run this site lives at [AI-assisted engineering](/ai-development/).]]></content:encoded>
      <pubDate>Sun, 14 Jun 2026 03:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/13/password-protect-cloudfront-static-site/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/password-protect-cloudfront-static-site.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>Reading My Own Handwriting With an AI That Can Actually See</title>
      <link>https://joshuaayson.com/2026/06/13/handwriting-ocr-with-ai-vision/</link>
      <description>Tesseract could not read a word of it.

I have years of handwritten journals, the actual paper kind, and I wanted them on this site. The obvious first move is optical character recognition, and the ob...</description>
      <content:encoded><![CDATA[Tesseract could not read a word of it.

I have years of handwritten journals, the actual paper kind, and I wanted them on this site. The obvious first move is optical character recognition, and the obvious tool is Tesseract, which is good, free, and everywhere. It is also built for printed text. Pointed at my cursive it returned something between a ransom note and static. Not a few errors to clean up. Garbage, top to bottom, page after page.

That makes sense once you think about what the old OCR actually does. It looks for the shapes of known letters in clean rows. Handwriting has no clean rows, my letters connect and lean and change shape depending on what came before them, and half the time a word is only legible because of the words around it. Reading cursive is not character recognition. It is closer to reading, the comprehension kind, and the old tools do not do that.

## What changed

A vision model does. When you hand a modern multimodal model an image of a page, it is not matching letter shapes against a font. It is doing the same thing you do when you read a friend's bad handwriting: using context, expectation, and the whole line at once to decide what a squiggle most likely says. Claude reads my cursive. Not perfectly, but at the level of a patient human who has seen my writing before, which is exactly the level I needed.

So the pipeline is simple, and most of it is not the AI part.

A journal becomes a scanned PDF. A script splits the PDF into one image per page and scrubs the scanner app's watermark out of the corner, because that watermark sits right on top of the text on the last line and the model will dutifully try to read it. Each clean page goes to the vision model, which returns a transcription. Anywhere it is unsure, it marks the spot rather than guessing confidently, which matters more than it sounds, because a confident wrong word is far more expensive than a flagged uncertain one.

## The part I do not automate, and would not

Then I read it. Every word, against the actual notebook open next to me.

This is the one exception to how I work everywhere else. With code, I have written about how reading turned into triage, because there is more of it than any person can read start to finish. With my own handwriting the opposite is true. There is not that much of it, it is mine, and the whole point is that it comes across as I wrote it and not as a model smoothed it. So I read all of it, slowly, and I fix what the machine misheard. The model does the seeing. I do the deciding about what the words are. That division is the entire design.

## How it gets better

The first batch was the worst batch, and on purpose.

After I correct a transcription, the misreads do not just get fixed and forgotten. They go into a lessons file, paired with what the word actually was. Over batches that file becomes a record of how the model tends to misread me specifically, plus a small dictionary of the words and coinages I use that no general model would guess. The next batch starts from those priors. The model is not learning in any deep sense between runs, but I am feeding its next first pass everything the last pass got wrong, and the first-pass accuracy climbs because of it. The work compounds. Batch ten is much less correcting than batch one.

That is the shape I keep coming back to in all of this. The machine is extraordinary at the mechanical seeing that used to be impossible, and useless at the one judgment that actually matters, which is whether the words are mine. So you build the pipeline to do the part it is good at, you keep yourself in the loop for the part it is not, and you give it a memory of its own mistakes so the boundary between the two keeps moving in your favor. The rest of how I build this way is at [AI-assisted engineering](/ai-development/).]]></content:encoded>
      <pubDate>Sun, 14 Jun 2026 01:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/13/handwriting-ocr-with-ai-vision/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/handwriting-ocr-with-ai-vision.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>I Compiled My Whole Blog Into One File at Build Time</title>
      <link>https://joshuaayson.com/2026/06/13/compiling-a-blog-into-one-build-cache/</link>
      <description>There is a 4.8 megabyte TypeScript file in my repository that I did not write. A script writes it, on every build, and I commit the result into git like it was mine. Most build advice would tell me th...</description>
      <content:encoded><![CDATA[There is a 4.8 megabyte TypeScript file in my repository that I did not write. A script writes it, on every build, and I commit the result into git like it was mine. Most build advice would tell me that is a mistake. I do it on purpose, and after a year of living with the decision I would make it again.

The file is the whole blog. Every published post, every draft, every book chapter, around five hundred entries, flattened into one big typed array that the pages import directly. The markdown is still the source of truth. It still lives in folders, one file per post, the way it should. But the pages never read those folders. They read the array.

## Why not just read the markdown

This is an Astro site, and Astro is perfectly happy to read markdown at build time. For a while it did. The problem was not any single page. It was that almost every page needs to know about the others.

The related-posts block needs the other posts. The category indexes need every post in a category. The hub page needs the whole AI cluster. The sitemap needs all of it, and so does the internal-link graph I built to audit the site. Every one of those was reaching into the same folders, reading the same hundreds of files, parsing the same frontmatter, running the same logic to filter drafts and normalize dates and derive slugs. The work was duplicated everywhere and it got slower as the site grew.

So I moved the reading out of the pages entirely. A prebuild step runs once, reads all the markdown, runs the shared loader logic a single time, and writes the result into one file. After that, every page that needs content imports an array that is already parsed, already filtered, already typed. No file system in the hot path. No parsing repeated two hundred times. The page layer stops being a thing that reads markdown and becomes a thing that queries a list.

## The part people will argue with

Committing a generated file is the choice that gets the side-eye, and I understand why. Generated artifacts in version control are usually a smell. They go stale, they bloat diffs, they invite the question of which copy is real.

I keep it anyway, for three reasons that turned out to matter more than the tidiness.

The build is deterministic and fast, because the expensive step already happened and its output is sitting right there. A content change shows up in git as a content diff, which is a readable audit trail of what actually changed on the site, not just which source file I touched. And the site can build even if the loader has a bad day, because the thing the pages depend on is data, not code that has to run correctly at the worst possible moment.

## The cost

There is a real price, and I am not going to pretend there is not. The cache and the markdown can drift. If I edit a post and forget to regenerate the file, the post changes and the site does not, and for a confusing few minutes I am debugging a problem that does not exist because I am looking at the new markdown and the old cache.

That has bitten me. The fix is not to be more careful, because careful is a feeling. The fix is to wire the regeneration into the build so it cannot be skipped, and to treat the commit as part of editing the post rather than a separate chore. The generated file is only safe because the thing that keeps it in sync is automatic. A precomputed cache you have to remember to update is a bug with a delay on it.

That is the whole trade, and it is a general one. When reading is expensive and happens in a lot of places, precompute it once into a shape that is cheap to read, and then pay the standing cost of keeping the precomputed thing in sync with the truth. The win is real and so is the bill. I run the same pattern on the internal-link graph and on the search index, and it is the same lesson every time: the speed is free, the consistency is not, and you buy the consistency with automation or you do not really own it. The rest of how I build this site lives at [AI-assisted engineering](/ai-development/).]]></content:encoded>
      <pubDate>Sat, 13 Jun 2026 23:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/13/compiling-a-blog-into-one-build-cache/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/compiling-a-blog-into-one-build-cache.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>I Wrote a Linter That Strips the AI Tells From My Own Writing</title>
      <link>https://joshuaayson.com/2026/06/13/how-to-detect-ai-writing-tells/</link>
      <description>The em dash is the easy one.

I can catch every em dash I will ever type with about nine lines of shell, and I do, on every commit. The script walks my published posts and the book chapters and fails ...</description>
      <content:encoded><![CDATA[The em dash is the easy one.

I can catch every em dash I will ever type with about nine lines of shell, and I do, on every commit. The script walks my published posts and the book chapters and fails the commit if it finds a real em dash, the YAML-escaped version of one, a spaced double hyphen that the markdown renderer would turn into a dash, or the space-less `word--word` that slips past everyone. Then it runs a second time after the build, against the rendered HTML, because the sneaky ones do not come from prose. They come from a title in the frontmatter or a string in a template, and the only place you can be sure to catch them is the page a reader actually sees. Anything that reached the HTML gets caught, no matter where it came from.

That gate works. It has never once let an em dash through since I wired it in. And it taught me the thing this whole post is about, which is that the em dash was never really an AI tell. It is a typographic habit. The real tells are harder, and they do not survive contact with a regular expression.

## The ones a script can catch

A few of them are mechanical enough to grep for, so I do.

Figurative "lands" and "resonates," the ones that show up as "the idea lands" or "that really resonated." A literal rocket can land and a literal string can resonate, so the script cannot just ban the words, but it can flag them for me to look at. "The part nobody talks about," in every costume, which is a move that fakes a secret out of a common observation. And the opener I caught myself using on essay after essay: "I have spent fifteen years doing X, and here is how I use AI." Every AI-engineering blog opens that exact way now. I had eight of them.

So I grep for the strings. But here is what I learned the first time I did: the moment you catch one, the writer just reaches for the synonym. Swap "resonated" for "stuck with me," swap one credential opener for another, and the sentence still reads like a machine wrote it. The generated feeling survives the word swap, because the tell was never the word. It was the register the word arrived in.

## The ones it cannot

You cannot grep for register. You cannot grep for a sentence that is technically correct and completely lifeless, or for a paragraph that resolves a little too neatly, or for the particular evenness that generated prose has when nothing in it was ever uncertain.

So the second layer is not a linter at all. It is a judgment, and the rule I use for it is older than any of this. Read the thing aloud against a sample of my own older writing, and if it does not sound like me, rewrite it until it does. I keep a body of my freewriting as the reference and the standard is written down so it cannot quietly drift. The only reliable detector of "does this sound like me" is me, or something that has read enough of me to stand in.

A blocklist cannot do that job, and this is the part most AI-tell guides get wrong. Some of the words on every generic list are genuinely mine. I use "unleash" and "palpable" and "realm" in their old physical sense, the way I have used them for years, and a literal-minded pass that strips them in the name of de-robotizing my prose just deletes my actual voice. The disqualifier is never the word. It is whether the word showed up in the generic figurative register or the real one, and no script knows the difference.

## The system leaks, on purpose

Here is the state of this. It is not a finished detector. I find new tells after they have already shipped, on pages that were live for weeks. When I find one I add it to the gate if it is mechanical and to the written standard if it is not, and lately I have started pointing an agent at my own published archive and asking it where I still sound like a machine. It finds things. Some of them I argue with. The list is not done and it is not going to be done, because the writing keeps maturing and the tells move with it.

That is the same loop I run on everything: when a failure gets past you, you do not just fix the one instance, you build the thing that catches the next one, and you accept that you are never fully ahead of it. I wrote about that habit in the engineering context in [Recursive DevOps](/2026/06/05/recursive-devops/). It turns out prose has the same shape.

If you write with AI, this is the whole takeaway. You need two different things, and only one of them can be automated. You need a gate for the mechanical tells, the dashes and the dead phrases, which a script handles forever once you write it. And you need a taste oracle for the rest, a real sense of your own register that you either supply yourself or train something to imitate from a corpus of you. The first one I can hand you. The second one is the actual writing, and it was always going to be. The rest of how I work this way lives at [AI-assisted engineering](/ai-development/).]]></content:encoded>
      <pubDate>Sat, 13 Jun 2026 21:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/13/how-to-detect-ai-writing-tells/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/how-to-detect-ai-writing-tells.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>How I Gave CloudFront a Content-Security-Policy Without Blanking My Own Site</title>
      <link>https://joshuaayson.com/2026/06/13/content-security-policy-static-site/</link>
      <description>A strict Content-Security-Policy on a static site allowlists inline scripts by hash. Change one script, forget to update the hash, and every page renders blank. The incident that taught me, and the deploy guard that ends it.</description>
      <content:encoded><![CDATA[The site went blank on a Tuesday. Not down. Blank. The images loaded, the favicon loaded, and everything else was white. No menu, no text, no error. Locally it was perfect. I had deployed maybe forty times the same way. This time the homepage came back as a clean white rectangle with three pictures floating in it.

It was not a build failure and it was not a bad deploy. It was a security header doing exactly what I had told it to do.

## What I had done

A few weeks earlier I had put a real Content-Security-Policy on the site. The kind without `unsafe-inline`. If you are serving a static site from S3 behind CloudFront, a strict CSP is one of the highest-value things you can add, because it turns a whole class of injection attacks into a non-event. The browser will only run scripts you have explicitly blessed.

The way you bless an inline `<script>` block is by its hash. You take the exact bytes between the tags, run them through sha256, base64 the result, and put `'sha256-...'` in the policy. The browser hashes every inline script it finds and runs only the ones whose hash is on the list. One character different, different hash, blocked.

That is the trap, and I walked straight into it.

## Why it broke

I had edited one inline script. It is the small block in my base layout that sets the theme before the page paints, so dark-mode users do not get a white flash on every navigation. To do that without a flash, the script starts the page at `visibility: hidden` and then clears it once the theme is applied. Hide first, decide, reveal.

I changed one line in that block. Reformatted it, really. The behavior was identical. But the bytes were not, so the hash was not, and the CloudFront policy still listed the old hash. The browser found the script, hashed it, did not find a match, and refused to run it.

The script that never ran was the one whose entire job was to undo `visibility: hidden`. So every page loaded its full HTML, sat there correctly structured and completely invisible, and waited for a reveal that the browser had just blocked. View-source showed all the content. The console showed the CSP violation. The page showed nothing.

## The fix, and then the real fix

The immediate fix is mechanical. I have a script, `hash_inline_scripts.py`, that walks `dist/`, pulls every inline script that is not a JSON-LD data block, computes the sha256, and prints the allowlist. You run it after a build, take the new hashes, and update two places: the live CloudFront Response Headers Policy, and a `response-headers-policy.json` checked into the infrastructure repo so the policy is version-controlled instead of living only in the AWS console. Mirror them or they drift, and a drifted security policy is a bug you cannot see in the diff.

That fixes the symptom. It does not fix the part where the whole thing depended on me remembering to do it at the exact moment I was thinking about something else.

So the real fix is a guard. `pre-deploy-csp-check.py` runs before anything uploads. It scans the build for inline scripts that appear on a lot of pages, the common ones like the theme block and the navigation, because those are the scripts that take the entire site down rather than one page. For each common script it checks whether its hash is present in the live policy. If a hash is missing, the deploy fails. Loudly. Before a single file moves.

The deploy now refuses to ship a site that would render blank. That is the sentence I actually wanted. Not "be more careful." The careful version had already failed once and it will fail again, because careful is a feeling and a build step is a fact.

## What I would tell you

If you put a strict CSP on a static site, and you should, understand that inline scripts plus hash allowlisting is a sharp edge and plan for it on day one. You have two clean ways out. Move every script into an external bundled file so there is nothing inline to hash, which is the simplest if you can pay the small no-flash-theme cost. Or keep the few inline blocks you actually need, automate the hashing, and put a guard in front of the deploy so a stale hash can never reach production. I kept two inline blocks for the theme load and bought the safety with the guard.

The general lesson is older than CSP. The most dangerous failures are the ones where the system is working perfectly and the configuration is wrong, because nothing throws, nothing logs an error, and the tool you would reach for to debug it is reporting success. A blank page with a 200 status and all its HTML intact is that failure wearing a costume. When something is impossible, check the thing that is succeeding.

This is the same loop I run on everything now: when a failure teaches you something, you do not just fix it, you build the system that makes that failure impossible to ship again. I wrote about that habit in [Recursive DevOps](/2026/06/05/recursive-devops/), and about rebuilding this whole site under that discipline in [Rebuilt My Site in Agent Mode](/2026/06/03/rebuilt-my-site-in-agent-mode/). If you are choosing tools for this kind of work, my comparison of the two I lived in is [Claude vs Copilot for DevOps](/2026/06/02/claude-vs-copilot-for-devops/). The rest of the field notes live at [AI-assisted engineering](/ai-development/). The smallest place to start, though, is to go read your own deploy script and ask it one question: what is the worst thing it will let you ship without complaining?

## Update, June 2026: I took the simpler way out, and the guard earned its keep

I am leaving the original below rather than quietly editing it, because the change of mind is the useful part.

When I wrote this, I kept two inline blocks for the theme load and bought safety with the deploy guard, and I called moving everything to external files the simpler way out that I had chosen not to take. Then I went to upgrade the framework, and the guard caught exactly what it was built to catch: the new version re-minified one of those inline scripts on its own, the hash changed, and the deploy stopped itself before it could blank the site. The cost I had dodged by keeping the scripts inline came due, on a change I did not control. It was a strange thing to be happy about a failed deploy, but that is the whole point of the guard, and here it was doing the job in the wild.

So I took the way out. The interactive scripts now live in their own files, served from the site itself, with nothing inline left to hash. The one piece I cared about most, the small block that reveals the page once the theme is set, got its own tiny file on purpose, so a bug anywhere else can no longer leave the page hidden. The no-flash cost I had braced for never really showed up, because that reveal was already waiting for the page to parse before it ran. I had been carrying the fragility without getting much for it.

That groundwork paid off sooner than I expected. The larger upgrade I had been circling finally landed, the kind that rewrites a lot of generated code in one pass. Because the scripts were already external, there was almost nothing to re-bless by hand, just one small file the framework generates for an interactive page, where before it would have been a scramble across the whole site. A second check earned its keep the same day: the one that pings a short list of must-work pages after every deploy caught a page that had quietly changed address during the upgrade, and stopped the deploy before anyone could land on the empty spot. Fix, rebuild, confirm. The lesson did not change, it just got tested at a bigger size. The job was never to be more careful. It was to build the thing that is careful for me, and then to actually listen when it complains.

What is left inline now is one stable block that the framework copies through untouched, so a version bump can no longer change a hash out from under me. The guard stays, but it has almost nothing left to guard. The setup in the original post was not wrong. It was the right call for the moment and the wrong call for the next one, which is most engineering decisions if you keep them long enough.

Then I took the last step, and it is the part I am happiest with. A guard can only ever tell you a hash is missing; you still have to go fix the list. So I stopped keeping the list by hand at all. The deploy now reads the finished site, works out the exact set of scripts it actually contains, and writes that into the policy itself, every time, before anything goes live. A changed script, a new one, even a generated one I did not write by hand gets blessed on the way out the door. The list cannot fall behind the site, because the site is now what produces the list. That is the whole arc of this post in one move: I started by being careful, got burned, built a thing to catch me when I was not, and finally handed the care to the build entirely. The thing I wanted all along was not a safer habit. It was a system that stays correct without me remembering to keep it that way.]]></content:encoded>
      <pubDate>Sat, 13 Jun 2026 17:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/13/content-security-policy-static-site/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/content-security-policy-static-site.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>Agent Mode vs Autonomous Mode: The Difference Is Who Closes the Loop</title>
      <link>https://joshuaayson.com/2026/06/12/agent-mode-vs-autonomous-mode/</link>
      <description>Agent mode and autonomous mode get used interchangeably and they are not the same thing. The difference is who closes the loop: you, after every task, or the system, on a schedule. A working engineer&apos;s disambiguation.</description>
      <content:encoded><![CDATA[Agent mode and autonomous mode get used as if they were synonyms. They are not, and the difference matters more every month, because it decides how much of your system you are actually supervising.

Here is the distinction in one line: **in agent mode, you close the loop. In autonomous mode, the system does.**

## Agent mode: directed, verified, yours

Agent mode is when you give an AI real access to your codebase and direct it through tasks: read the repo, make the change, run the tests, report back. The agent does the work; you do the judgment. Every task ends at your desk. You read the diff, you approve or reject, and nothing ships that you did not see.

I wrote the full definition in [What Is Agent Mode?](/2026/06/02/what-is-agent-mode/) The key property is that the human is inside the loop at task granularity. The agent's autonomy lasts exactly one assignment.

## Autonomous mode: scheduled, conditional, supervised differently

Autonomous mode removes your hand from the individual step. The system runs on a trigger, a schedule, or a condition: the nightly job that triages new issues, the pipeline that retries and self-heals, the agent that watches a queue and acts on what arrives. You still set the boundaries. You do not approve each action, because you are not there when it happens.

The full definition lives in [What Is Autonomous Mode?](/2026/06/02/what-is-autonomous-mode/) The key property is that verification moves from per-task to per-boundary: you review the rules, the limits, and the outcomes, not each act.

## It is a dial, not a switch

In practice the two are ends of a dial, and the dial is labeled trust.

Work I cannot yet predict gets agent mode: I direct, I read closely. Work the agents have done correctly fifty times starts earning slack. First I stop watching it run and just read the result. Then the result only comes to me when something is unusual. Somewhere along that slope the work has quietly crossed into autonomous mode, and the engineering question is whether you noticed the crossing.

That is the failure mode to respect: autonomy by erosion. Nobody decides to stop supervising; the supervision just thins. The fix is to make the crossing explicit. When a task graduates from agent mode to autonomous mode, that should be a decision with a date on it, the way a deploy is, with boundaries written down: what it may touch, what it must never touch, what gets escalated.

## When to use which

Use **agent mode** for anything novel, anything touching production state, anything where the cost of a confident wrong answer is high, and anything you have not watched succeed repeatedly. Which, when you are starting, is everything.

Use **autonomous mode** for work that is frequent, reversible, and boring: triage, formatting, dependency bumps, report generation, the rebuild that runs every night whether you watch it or not. Frequent earns the trust. Reversible caps the damage. Boring is what makes supervision-per-task a waste of a human.

## It is not only about trust

Trust is the main axis, but it is not the only one, and treating the choice as purely about risk oversimplifies it. In practice the dial also turns on constraints, cost, and plain utility. Sometimes the environment decides for you: a locked-down setup, a policy, no network, and the choice is made before you make it. Sometimes it is cost, because an autonomous loop left running can burn through tokens and compute that a few surgical passes would not, or the reverse. And often it is just utility, which way of working gets this particular job done with the least friction. The answer to "agent or autonomous" is frequently "it depends," and the things it depends on are worth naming instead of pretending the rule is clean.

You also do not have to pick one for the whole day. I routinely run both at once: an agent grinding autonomously on a throwaway branch while I work surgically beside it on the part I actually care about. And here is the detail that dissolves the question almost entirely: the same tool does both. Claude Code has a permission mode you can flip. Leave it asking before each step and it is surgical, one approved action at a time. Switch it to allow-all, or auto-accept, and that same agent runs the loop on its own. The other agentic tools have the equivalent. So the mode is not a property of the tool you reached for. It is a setting you choose, per task, for your own reasons, and knowing why you put the dial where you did is the actual skill.

The deeper shift behind both modes, what it does to how you think about engineering work at all, is the subject of [Agent Mode Changes the Shape of Thought](/2026/06/05/agent-mode-changes-the-shape-of-thought/). And the day-to-day method for working this way, including how trust gets earned task by task, is in [The AI-Assisted Engineering HOWTO](/2026/06/06/ai-assisted-engineering-howto/).

One loop closed by you, one closed by the system. Know which one you are in. That is the entire distinction, and most of the safety.]]></content:encoded>
      <pubDate>Fri, 12 Jun 2026 18:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/12/agent-mode-vs-autonomous-mode/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/agent-mode-vs-autonomous-mode.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>How I Use AI as a Senior Engineer: Where the Day Actually Goes</title>
      <link>https://joshuaayson.com/2026/06/12/how-i-use-ai-as-a-senior-engineer/</link>
      <description>Not a tools list. The tools changed three times this year; what changed underneath is where the hours go: specs in the morning, batch review in the afternoon, and the judgment work that never left.</description>
      <content:encoded><![CDATA[Everyone wants the tools list. The tools list is the least interesting part.

The tools changed three times this year. What stayed constant is more useful to write down: where the hours go now, what I hand off, and what never left my desk. The work underneath spanned infrastructure, applications, this site, and creative systems that have nothing to do with my day job, and the same shape held across all of it.

## The day, roughly

Mornings are for specs. Before agents, my morning was often the first implementation push of the day. Now it is writing: what needs to exist, what done looks like, what the constraints are, what the agent should not touch. A good spec takes twenty minutes and saves three hours. A lazy spec costs you the afternoon, because the agent will build the wrong thing with great competence and you will read all of it before you find out.

Then the delegation. Several pieces of work running at once, each one scoped so it can fail independently. This is the part that genuinely did not exist before. One stream is a migration, one is a bug, one is a draft of something I am not sure about yet. Multiples of output. The constraint stops being my typing speed and becomes my attention.

Afternoons are batch review. Everything the agents pushed to staging gets read in one sitting, with the three-pass review I described in [my AI code review workflow](/2026/06/11/ai-code-review-workflow/). Batching matters more than it sounds. Context-switching between writing specs and reading diffs all day shreds both. Separating them keeps each one sharp.

## What I hand off

The pattern under everything I delegate: work where the destination is known and the path is mechanical.

Migrations. Scaffolding. Test coverage for code that already works. Sweeps across a codebase, the kind where the same change needs to happen forty times with small variations. Config plumbing. First drafts of documentation. The bottom ninety percent of any task whose top ten percent I care about.

I also hand off investigation, which surprised me. "Find every place this assumption appears" is agent work now. The agent reads faster than I do and does not get bored on file thirty. What it brings back still needs my eyes, but the gathering is no longer my job.

## What stays

Deciding what to build. That one never moves. The cost of writing code fell through the floor and the cost of knowing what to write did not budge, which is the whole story of [how AI is changing software engineering](/2026/05/27/how-ai-is-changing-software-engineering/) compressed into one sentence.

Naming. Architecture. The judgment call on whether a change belongs at this layer or two layers down. Taste, which sounds soft until you watch its absence compound across a hundred agent-written diffs. And reading, though what reading means at this volume is worth saying. There is more shipping than any one person reads start to finish: the code, the configs, the ADRs, the prompts, the docs. So reading turned into triage. I read the places where a mistake is expensive and the seams where pieces meet, and for the rest I lean on the systems that read for me, the tests, the gates, the second agent whose whole job is to find what I would have missed. What I will not do is stop reading my own systems entirely, because the mental model is the part I cannot hand off, and a model you have stopped maintaining quietly rots.

## What it costs the body

There is a physical cost to working at this multiple. The pressure behind the eyes after a long parallel session, the way the speed bends your sense of time. I wrote about it in [Working at the Frontier](/2026/06/08/working-at-the-frontier/), and I bring it up here because no workflow advice is complete without it. Water. Breaks. The heat is information. Work near the forge without standing in the fire.

## What the job is now

The thing I keep coming back to is that the agents did not compress the experience ladder. They moved it.

Anyone with agents can produce volume. Producing volume that holds up takes something the model does not have yet: a verification instinct, the kind you only earn by watching systems fail in production and being the reason a few of them did. I do not think that makes me special. It makes me someone who has made enough of the mistakes to feel the next one coming. Applied to ten times the throughput, that instinct is most of the job now: less producing, more conducting, and the conductor is responsible for every note, including the ones an agent played.

The cognitive load is real and it is different from the old load. I wrote about that trade in [The Cognitive Cost of Modern Software Engineering](/2026/06/05/the-cognitive-cost-of-modern-software-engineering/). The short version: you trade the strain of producing for the strain of judging, and judging all day is its own discipline.

## The work on the work

One more thing stays, and I underrated it at first. The way I work is not a method I arrived at and locked. It is a system like any other, which means it leaks, so I study it and [refactor it the way I would refactor code](/2026/06/02/life-ops-running-your-life-like-software/). The specs, the review passes, the ADRs that record why a decision went the way it did, the gates that catch my own mistakes before they ship, all of it keeps getting revised. A lot of that revision now happens in agent mode too. I point an agent at my own process and ask it where the process breaks. Leveling up the work and leveling up the way I do the work turned out to be the same activity, and I am nowhere near finished with either.

If you want the operating manual version of all this, it is in [The AI-Assisted Engineering HOWTO](/2026/06/06/ai-assisted-engineering-howto/), the working method for directing an agent through your repo is in [Agentic AI Development](/2026/05/30/agentic-ai-development-workflows/), the tool question I get asked about most is settled in [Claude vs Copilot for DevOps](/2026/06/02/claude-vs-copilot-for-devops/), and the full hub of this work lives at [AI development](/ai-development/). The place to start, though, is smaller: pick one mechanical task tomorrow, write a real spec for it, hand it off, and read the change that comes back, the costly parts first. The workflow grows from there.]]></content:encoded>
      <pubDate>Fri, 12 Jun 2026 16:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/12/how-i-use-ai-as-a-senior-engineer/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/how-i-use-ai-as-a-senior-engineer.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>My AI Code Review Workflow: Review the Change, Not the Typing</title>
      <link>https://joshuaayson.com/2026/06/11/ai-code-review-workflow/</link>
      <description>The code got cheap. The review did not. Here is the review workflow I actually use when AI agents write most of the diff: three passes, an adversarial second agent, and the discipline of reading what ships.</description>
      <content:encoded><![CDATA[The code got cheap. The review did not.

That is the whole situation in two sentences. When an agent can produce a competent multi-file change in minutes, the bottleneck moves to the person reading the diff. Most of the advice I see about AI code review is written by people who have not lived there yet. This is the workflow I actually use, every day, on real systems.

## The shape of the problem

Reviewing agent code is not like reviewing a colleague's PR. A colleague gets tired and writes less. An agent does not, so the volume is relentless and the failure modes are different. An agent's code usually compiles, usually passes the obvious test, and usually looks right. When it is wrong, it is wrong in a confident, well-formatted way. The typos are gone. The bugs wear suits now.

So the review cannot be a typo hunt. It has to operate at the level of the change itself: what was asked for, what was delivered, and what came along for the ride.

## Three passes

I read every diff three times, fast. Each pass asks one question.

**Pass one: does it do the thing.** Not "does it look like it does the thing." I run it. Tests, build, the actual command, the actual page. If the agent says tests pass, I want to see them pass. A green checkmark I did not watch happen is a rumor.

**Pass two: does it belong.** This is the architecture pass. Is the change at the right altitude? Did the agent solve the problem where the problem lives, or did it patch the symptom three layers up? Did it invent a new pattern when the codebase already has one? Agents are eager. They will happily add a second way to do something rather than find the first way. This pass is where most of my rejections come from.

**Pass three: what came along for the ride.** Scope creep, dependency additions, config changes, the helpful little refactor nobody asked for. I read the file list before I read the files. If a one-line fix touches nine files, the diff has a story to tell and I want to hear it before I approve it.

Three passes sounds slow. It is not. Each one is a single question, and a single question reads fast. Ten minutes on a medium diff. The discipline is not the time, it is refusing to let the passes blur together into one vague skim.

## The adversarial second agent

Here is the part that changed my practice this year: I have one agent review another agent's work, and I prompt the reviewer to refute, not to assess.

"Assess this change" gets you a polite summary. "Find what is wrong with this change, assume something is" gets you a hunter. The reviewer agent does not get tired, does not get attached to the code, and was not the one who wrote it, so it has no ego in the game. It catches a real bug maybe one time in five. That rate is worth it, because the cost is a few minutes of wall-clock I was spending anyway on pass one.

The verdicts still come to me. The agents generate findings; I generate judgment. That division has not moved and I do not expect it to.

## Gates that earned their place

Every automated check in my pipeline is there because something bit me once. Lint, typecheck, a security scan, and a couple of [project-specific checks that would sound strange anywhere else](/2026/06/13/how-to-detect-ai-writing-tells/) but exist because a specific deploy broke a specific way. The pre-commit chain on this site runs four checks, and I can tell you the incident behind each one.

That is my test for adding a gate: it has to map to a real failure, not a hypothetical one. Speculative gates rot. Earned gates get maintained, because you remember the bite.

When an agent's change passes the gates, that clears the floor, not the bar. Gates catch the known failure modes. The review catches the new ones.

## What I refuse to automate

The reading. That is the line, and it is worth saying how the line holds.

I will let agents write the code, run the tests, draft the commit message, and argue with each other about the diff. The standard I hold for myself is that I read what ships, and most of the time I meet it. I am not going to pretend it is absolute. There are changes I end up verifying mostly through testing: I run the suite, I exercise the real behavior, I watch it work, and I read the shape of the diff without tracing every line. A mechanical sweep across forty files, generated test coverage, a migration I have watched succeed before. That is not me recommending it. It is what a high-volume day actually looks like when the writing gets ahead of the reading.

What does not move is the direction. I still have a lot of code to review, always, and reading is the thing I protect first and give up last. The day you stop reading is the day your mental model of the system starts to drift, and a senior engineer with a stale mental model is just a slow junior with better stories.

The review is where you stay current with your own codebase. Hand that away and you have handed away the job.

## Where this fits

This workflow is one loop inside a larger working method: specify, delegate, verify, record. I wrote the full manual in [The AI-Assisted Engineering HOWTO](/2026/06/06/ai-assisted-engineering-howto/), and the argument for why this is a discipline and not a shortcut in [AI-Assisted Development Is Not Vibe Coding](/2026/05/07/ai-assisted-development-is-not-vibe-coding/). If agent mode is still a fuzzy term, start with [What Is Agent Mode?](/2026/06/02/what-is-agent-mode/) When the agents start reviewing the systems that build the systems, that is [Recursive DevOps](/2026/06/05/recursive-devops/), and it is closer than it sounds. The tool you run all this in matters less than the discipline, but if you are weighing them, [Claude vs Copilot for DevOps](/2026/06/02/claude-vs-copilot-for-devops/) is my take.

The longer argument is the book: [AgentSpek](/books/agentspek/), free to start reading here.]]></content:encoded>
      <pubDate>Thu, 11 Jun 2026 16:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/11/ai-code-review-workflow/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/my-ai-code-review-workflow.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>Working at the Frontier: What It Actually Feels Like</title>
      <link>https://joshuaayson.com/2026/06/08/working-at-the-frontier/</link>
      <description>A field report from inside sustained agent-mode work: the heat behind the eyes, the way speed bends your sense of time, what it costs the body, and the practice that lets you build at the frontier anyway.</description>
      <content:encoded><![CDATA[View Original Handwritten Notes
[dflip id="working-at-the-frontier" source="/pdfs/working-at-the-frontier-2026-06-08.pdf"][/dflip]


There is a heat that comes with working alongside capable agents, and it is worth talking about, because almost nobody does. Much like a too-tight headband, or a beanie a size too small, it is a familiar kind of pressure, and it surfaces, eventually, as a real headache. When I notice it now I ask the plain questions first. Have I had enough water. When did I last take a break. I look out the window. I name something outside, a tree, a roofline, the color of the sky, and if the heat is still there I put on shoes and walk until it goes. The heat is information. It is a sign, the way a runner's blisters are a sign, that a good limit has been reached.

Because this is closer to training than to typing. You feed yourself a measured dose of hormesis, the useful kind of stress, the kind that builds cognitive holding capacity instead of breaking it, and you learn to work with the heat without standing in the fire so long that you burn out. You work near the forge where new ideas are born the way stars are born out of a nebula. Like all training, the worn synapses take their own time to come back. But the mind itself is resilient, and underused, and capable of far more than we tend to ask of it. What limits it, I think, is language, the narrow channel cognition has to pass through to become anything you can share. Once thoughts can travel faster, the thinking speeds up with them. I followed that same idea down into sound itself in [The Language of Sound](/the-language-of-sound/): you cannot make a thing you cannot name.

Both the speed and the ability to scale cognition change your perception of time. You get thrown into project-level wormholes, folding hours against the gracious estimates the tools hand you, until the only real limit becomes a question of how slow you are, and where the time went. All of it is in service of building something useful, and that is exactly where the huge missed opportunity lives, because most people take the speed and waste the build. So you develop the practice the way you would develop morning pages, by showing up to it. It is fine to vibe code, to try things, to let the agent run, and it should be encouraged. But as the system grows in complexity you add the appropriate layers in the same motion, the planning, the context, the guardrails, the structure, at the rate the complexity actually demands them.

<div class="image-container center">
  <img src="https://joshuaayson.com/images/essays/2026/06/age-of-agents-triangle.webp" srcset="/images/essays/2026/06/age-of-agents-triangle-480.webp 480w, /images/essays/2026/06/age-of-agents-triangle-768.webp 768w, /images/essays/2026/06/age-of-agents-triangle.webp 1024w" sizes="(max-width: 768px) 100vw, 768px" alt="Vintage sci-fi poster of an all-seeing eye inside a triangle labeled Plan, Observe, and Act, titled Age of Agents" class="content-image" loading="lazy" />
</div>

I have started calling this the age of agents, and I draw the same small figure in the margin every time. Plan. Observe. Act. It is not only the speed. The results that come out of scaling cognition under the right direction are astounding, given the calibre of the output. What changes underneath is the shape of the work itself. The way you think about the job moves from implementation to design, to orchestration, to efficiency, to anything and everything in between. It is devops applied to the whole of it.

That shift drives a real need, for technical ability and for familiarity, leaning harder than ever into architecture, into quality, into security, and into cost, all of it broken down continuously and accurately and kept attached to what it actually costs. Here is what I could not have written down eighteen months ago. This lets you leap-frog across domains. Once you have a general grasp of a new territory, its codex and its language, once the vocabulary is understood, there is great power waiting on the other side of it.

With the right context and the right systems you get to a high standard in a field in far less time than it used to take, and you start to find what I call the edges. The places where, with proper tools and the meta-capability of these models to abstract models and patterns, you can take some of the most sophisticated machinery there is and model the domains, the systems, the cognition itself, and bring coherence to complexity. The overwhelming becomes navigable. The illegible becomes legible. You draw the maps that let you work near the furnace, close to the source of the heat and the energy, and still keep enough of yourself in reserve to make sense of it all, or to hold what has to be held, and carry it.

Don't panic.]]></content:encoded>
      <pubDate>Mon, 08 Jun 2026 08:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/08/working-at-the-frontier/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/working-at-the-frontier.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>The AI-Assisted Engineering HOWTO</title>
      <link>https://joshuaayson.com/2026/06/06/ai-assisted-engineering-howto/</link>
      <description>A practical, plain-spoken manual for building software with an AI agent: the setup, the loop, context management, and verified Claude Code and Copilot commands. Written like the old Linux HOWTOs, by someone who runs it daily.</description>
      <content:encoded><![CDATA[*Revision 1.1, June 2026. This is a HOWTO in the old sense: a plain manual you can read top to bottom and then go do the thing. I grew up on the Linux Documentation Project, learning the internet one HOWTO at a time. I wanted to write one for years. This is that document, for the skill I use most now. It has high-level tips and it has commands you can paste. Come back to it.*

## 0. Introduction

AI-assisted engineering is building software by directing an AI agent instead of typing most of the code yourself. Done well, it is the biggest change to how I work in fifteen years. Done badly, it produces confident garbage faster than you can read it.

This manual is the difference between the two. It is the setup, the loop, the commands, and the failure modes, written for an engineer who has used a chat assistant a few times and now wants to work this way for real, on a codebase that matters.

I run this with two tools and two models. Claude Code in the terminal. GitHub Copilot agent mode in VS Code. Sonnet for most of it, Opus when the thinking gets hard. The method outlives any one tool, but I am going to be specific, because a HOWTO with no commands in it is just an opinion.

### 0.1 Who this is for

You write or maintain real software. You have opened an AI chat window, pasted some code, and gotten useful answers back. You suspect there is more to it. There is. You do not need to be an expert. You do need to stay responsible for the output.

### 0.2 What this is not

This is not vibe coding, the practice of prompting and hoping and shipping whatever falls out. If you want that line drawn clearly, read [AI-Assisted Development Is Not Vibe Coding](/2026/05/07/ai-assisted-development-is-not-vibe-coding/) first, then come back. It is also not a magic-prompt collection. There is no incantation. There is a method.

## 1. What you need before you start

A short list. The rest of the document assumes you have it.

1. A real project under version control. Git, committed, clean working tree. This is your safety net and it is not optional. If you cannot get back to a known-good state in one command, fix that first.
2. A test suite, even a thin one. The agent will run it. Tests are how the machine checks its own work so you do not have to read every line by hand.
3. At least one agent with hands. Claude Code in the terminal, or Copilot agent mode in VS Code, or both. A chat box you paste into is the training-wheels version. You want the version that can read the repo, edit files, and run commands.
4. A few minutes to write down how your project works. That file beats any prompt trick, and section 4 is about building it.

## 2. The mental model: you stopped typing

The hardest part of this is not technical. You have to stop thinking of yourself as the person who writes the code.

For most of your career the bottleneck was your hands: how fast you turned an idea into correct syntax. AI moved that bottleneck. The cost of producing code fell to almost nothing. What did not get cheaper is deciding what to build and confirming it is right. That is where your whole job lives now. I wrote about the shape of this in [Agent Mode Changes the Shape of Thought](/2026/06/05/agent-mode-changes-the-shape-of-thought/), and about its hidden bill in [The Cognitive Cost of Modern Software Engineering](/2026/06/05/the-cognitive-cost-of-modern-software-engineering/). You become a director, not a typist. Direction is harder than it sounds.

Here is what that looks like at my desk. This is my own setup, on my own time. On my Organic Arts LLC projects and websites, where I set the rules, I run four to eight Claude Code terminals at once, each on a different task, with VS Code open beside them for review: reading the code and the markdown, making small tweaks by hand, stepping through git compares before anything gets committed. The terminals do the building. VS Code is where I look before I trust. My day job is its own world with its own approved tooling, and I am thankful to work somewhere that actively encourages AI-assisted engineering; there the setup is tighter and editor-first. The number of windows is not the point. The work is parallel now, and your job is to keep the parallel work coherent.

Hold that picture. Every tip below is really about protecting the two things only you can do, deciding and verifying, and handing the rest to the machine.

## 3. The two tools I use

Pick a tool with real repository access and learn it well. Two windows beat ten you half-know. Here is the stack I actually run.

### 3.1 Claude Code, in the terminal

This is where most of my building happens. You start it in the project directory:

```bash
claude                      # start an interactive session in the current repo
claude --model sonnet       # start on Sonnet (fast, my default)
claude --model opus         # start on Opus (deeper reasoning, harder problems)
```

Inside the session you talk to it in plain language and it does the work: reads files, writes the change across the codebase, runs the tests, reports back. You switch models mid-session when a task gets hard:

```text
/model opus                 # switch this session to Opus
/model sonnet               # switch back
```

`Shift+Tab` cycles the permission mode: ask-every-time, auto-accept edits, and plan mode (read-only, where it proposes a plan before touching anything). I live in ask-every-time for real work and plan mode when I am still deciding what to do. `Esc` interrupts it the moment it heads the wrong way. Do not wait politely for a bad run to finish.

### 3.2 Copilot agent mode, in VS Code

When I am already in the editor, or my setup is constrained, I use Copilot agent mode. Open the Copilot chat panel, switch it to Agent, and pick the model from the selector. The same two names are there: Claude Sonnet for daily work, Claude Opus when the problem is gnarly. Agent mode does what the terminal does, multi-file edits and a test loop, with the diff right there in the editor where you read it.

### 3.3 When I reach for which

The terminal wins when I want many things happening at once, or I am scripting, or the job is large. The editor wins when the change is small and visual and I want to eyeball the diff as it shows up in the tree. Neither is the "real" one. They run the same loop. Use the one whose friction is lower for the task in front of you.

## 4. Set up your workspace: the memory file

Before you ask the agent to do anything, give it a place to stand.

The single most useful thing you can do is write a project memory file: a document the agent reads every session that tells it how this project works. Each tool reads its own, and this is the part people get wrong, so be clear about it:

- **Claude Code** reads `CLAUDE.md` at the repo root. It also reads a personal one at `~/.claude/CLAUDE.md` for your cross-project preferences, and nested `CLAUDE.md` files deeper in the tree when it works in those folders.
- **Copilot agent mode** reads `.github/copilot-instructions.md` at the repo root.

They are not either-or. They are additional. If you use both tools, you keep both files, and you keep them saying the same thing. This repo carries both. Same content, two front doors.

Claude Code can write you a starting draft from the code itself:

```text
/init                       # generate a starter CLAUDE.md from the codebase
/memory                     # see which memory files are loaded right now
```

Put in the file what you would otherwise repeat out loud every session:

- What the project is, and how it is built, tested, and run.
- The conventions you actually enforce, in your own words.
- The parts that are dangerous to touch, and the rule for touching them.
- The mistakes the agent already made, so it stops making them.

Keep it lean. A long memory file is a memory file the agent skims and you stop maintaining; aim for something you would actually read. When it grows, split the detail into smaller files and pull them in with `@path` imports:

```markdown
See @docs/architecture.md for the system layout.
Testing rules live in @docs/testing.md.
```

This file turns your standing intent into something permanent. You write your standards once and they apply forever, instead of re-explaining them in every prompt. A good memory file is worth more than any clever phrasing, because it removes the need for clever phrasing. Appendix A has a starter you can copy into either file.

## 5. The core loop

Everything else is one loop, run over and over: **specify, delegate, verify, record.** I run it every day and wrote it up in full in [An AI Agent Workflow for Software Engineers That Actually Holds Up](/2026/06/02/ai-agent-workflow-for-software-engineers/). The working summary:

**Specify.** Get clear on what you want before you type a prompt. For anything past a trivial fix, write the intent down: the outcome, the constraints, what is non-negotiable. Vague in, vague out.

**Delegate.** Hand over the task, not the keystrokes. "Add rate limiting to the payments endpoint and update the tests" is a task. Let the agent read the code, make the change, and run the suite. Do not micromanage the implementation. You set the destination; it drives.

**Verify.** Read the diff. Run the tests. Check the real behavior, not just that a command exited zero. People skip this step and it is the one that matters most, so it has its own section below. The full version of how I do it is in [My AI Code Review Workflow](/2026/06/11/ai-code-review-workflow/): three passes, an adversarial second agent, and the rule that I read what ships, the costly parts first.

**Record.** When you make a real decision, write down why. I work off architecture decision records a lot of the time, one short ADR per real choice, plus a journal note for myself. An ADR pays off twice: it records why you did something, and next time it specifies the work, because a clear decision is already most of a clear prompt.

The loop holds because the first and third moves are exactly the moves an agent cannot make for you. That is the point of the whole method.

## 6. Context and token management

The agent only knows what is in its context window: the running record of your conversation, the files it has read, the test output it has seen. The window is large but not infinite, and a stuffed, stale window makes the agent dumber. Managing it is a real skill, so treat it like one.

Two commands do most of the work:

```text
/context                    # see what is filling the window right now
/clear                      # wipe the conversation, keep the project memory file
/compact                    # summarize the conversation so far and keep going
```

Use `/clear` between unrelated tasks. A fresh window for a new job is faster and sharper than one dragging an hour of irrelevant history. Use `/compact` when one long task has filled the window but you still need its thread; it keeps the gist and drops the noise. Check `/context` when answers start drifting; a full window is often the reason.

Model choice is the other lever. Sonnet is fast and cheap and handles most engineering work, so it is my default and I leave it there. I move to Opus when a task needs real reasoning: a thorny architecture decision, a bug that has survived two attempts, a plan with many moving parts. Then I move back. Running everything on the heavier model is slower and costs more without making the easy work any better. Match the model to the difficulty, not to your mood.

There is a sharper reason to care about all of this: tokens. The deeper you get, the more you feel it, especially as you near a plan limit or you are paying by the token. The skill that compounds is accomplishing more with fewer tokens, and it is worth treating as a craft of its own. A tight task that points the agent at the three files that matter costs a fraction of a vague one that makes it read half the repo just to orient itself. Clear between tasks so you are not paying to carry dead history. Keep the memory file short. Send big searches out as a subagent so the long output stays out of your main window. Reach for Sonnet first and save Opus for where the reasoning earns its higher price. Doing more with less is not a constraint here. It is the game.

## 7. Tips and tricks

The part I would have read first. Each of these I learned by getting it wrong.

1. **Commit before any big agent run.** A clean checkpoint means a bad run costs you a `git reset --hard`, not an afternoon. Treat the working tree as scratch paper the agent writes on.

2. **Work in small, verifiable units.** One coherent change at a time. A pile of changes you cannot review is a pile you cannot trust, however good it looks.

3. **Make the agent run the tests itself.** Do not run them and report back. Wire it so it sees the failures directly and iterates. Closing that loop is most of the magic.

4. **Green is necessary, not sufficient.** AI-generated code can pass every test and still be wrong, because the test never covered the thing that breaks. Passing tests buy confidence, not certainty.

5. **Verify behavior, not exit codes.** A command that exits zero did what it was told, which is not the same as what you wanted. For anything that touches the real world, look at the real world.

6. **Give it the error, not your summary of the error.** Paste the actual stack trace, the actual failing test, the actual log line. The agent is good with raw evidence and bad with your paraphrase.

7. **Fence the dangerous areas in writing.** If code must not change without care, say so in the memory file, not in your head. The agent honors written rules. It cannot read your worries.

8. **Say a correction once, in the memory file.** If you find yourself fixing the same thing twice, that fix belongs in the file, permanently.

9. **When it goes in circles, stop and re-specify.** An agent stuck in a loop is almost always an agent you under-specified. The fix is upstream, in what you asked, not in asking again louder.

## 8. Commands and hacks worth knowing

These are the moves that compound once you are past the basics. All of them are part of how I run a normal day.

**Headless mode, for scripting.** Outside a session, `-p` runs one prompt and exits. Good in scripts, git hooks, and CI:

```bash
claude -p "summarize the changes in the last commit"
cat error.log | claude -p "what is the root cause here?"
```

**Pick up where you left off.** A session is not gone when you close it:

```bash
claude --continue           # resume the most recent session in this repo
claude --resume             # choose from a list of past sessions
```

**Run agents in parallel without collisions.** This is how the four-to-eight-terminals setup actually works. Each agent gets its own git worktree, a separate checkout of the same repo on its own branch, so two agents editing at once never step on each other:

```bash
git worktree add ../proj-auth     -b feature-auth
git worktree add ../proj-logging  -b fix-logging
# open a Claude Code session in each directory; they cannot collide
git worktree list
git worktree remove ../proj-auth  # clean up when the branch is merged
```

**Teach it a repeatable job once.** A custom slash command is a markdown file of instructions you invoke by name. Drop it in `.claude/commands/` in the repo (or `~/.claude/commands/` for all your projects):

```bash
# .claude/commands/ship.md  ->  invoked as  /ship
# put your standard pre-deploy steps in that file in plain language
```

After that, `/ship` runs your checklist the same way every time. This is the lock-it-down move from the next section, made concrete.

## 9. Lock it down, or leave it open

There are two modes of working this way and you need both.

Sometimes I want the creativity of not locking things down. I give the agent room, leave the constraints loose, and let it surprise me. I try to encourage artistry in the outcome and in the system itself, not just correctness. This is the same instinct I bring to freewriting, the practice I call consciousness mining: keep the prompt loose, stay honest, get the ego out of the way, so something I did not plan has room to surface. You are fishing, and you want a wide net. A tight spec here kills the thing you were reaching for.

Other times I build for repetition and lock it down hard. A clear ADR. A strict memory file. Fences around the dangerous code. A custom slash command so the steps never drift. A task specified so tightly there is one reasonable result. That is the mode for work that has to be right and has to be the same every time.

The skill is knowing which one you are in. Leave a production change loose and you ship a subtle bug. Lock down an exploration and you kill the surprise you were after. Decide on purpose, at the start, which mode the task is, and do not drift between them by accident.

## 10. Common failure modes and how to fix them

Symptom, then cause, then fix.

**The output looks right and is subtly wrong.** Cause: you verified the build, not the behavior. Fix: exercise the actual feature. I once moved a site to a private origin; the change was correct except the new origin did not serve directory index files, so every subpage would have broken. The build was green. I caught it by loading a real page, not by trusting the log.

**It keeps reintroducing a mistake you fixed.** Cause: the correction lives in your memory, not the project's. Fix: write the rule into the memory file so it survives the session.

**Its answers start drifting and getting vague.** Cause: the context window is full of stale history. Fix: `/clear` for a new task, or `/compact` to keep the thread but drop the noise. Check `/context` when in doubt.

**It changed something you did not ask it to.** Cause: the task was broader than you thought, or the danger zone was not fenced. Fix: narrow the task, mark the protected areas in writing, reset to your last commit.

**It is slow and you want to just write it yourself.** Cause: the task is small enough that specifying it costs more than doing it. Fix: do the small ones yourself. The loop earns its keep on tasks big enough that direction beats typing. Not everything should be delegated.

**You shipped fast and now you do not understand your own system.** Cause: you skipped the record step, and speed without memory is debt. Fix: slow down on the decisions, write them down, read the diffs you waved through. The cognitive bill is real and it comes due.

## 11. Frequently asked questions

**Claude Code or Copilot agent mode?** I use both. Terminal for parallel and large work, the editor for small visual changes. They run the same loop. My longer comparison for engineering work is in [Claude vs Copilot for DevOps](/2026/06/02/claude-vs-copilot-for-devops/).

**Sonnet or Opus?** Sonnet for almost everything; it is fast and it is enough. Opus for the hard reasoning: thorny architecture, a bug that survived two attempts, a plan with many parts. Switch with `/model`, then switch back.

**CLAUDE.md or copilot-instructions.md?** Both, if you use both tools. Claude Code reads `CLAUDE.md`; Copilot agent mode reads `.github/copilot-instructions.md`. Keep both, keep them in sync. They are additional, not a choice.

**Is this just vibe coding with extra steps?** No, and the difference is the whole thing. Vibe coding skips specify and verify. This method is built on them. See [AI-Assisted Development Is Not Vibe Coding](/2026/05/07/ai-assisted-development-is-not-vibe-coding/).

**Can I let it run on its own?** Sometimes, with care. Autonomous mode runs the loop without you in it. When to trust it is its own question, covered in [What Is Autonomous Mode?](/2026/06/02/what-is-autonomous-mode/).

**Does this replace software engineers?** No. It moves the work. The cost of writing code fell; the cost of deciding what to build did not. [How AI Is Changing Software Engineering](/2026/05/27/how-ai-is-changing-software-engineering/) is the long answer.

**Does this apply to infrastructure?** Yes, and the payoff compounds there. The same loop runs on Dockerfiles, CI pipelines, and infrastructure code. [Recursive DevOps](/2026/06/05/recursive-devops/) is where I take that to its end.

## 12. Where to go next

This document is the entry point. The cluster behind it goes deeper:

- [AI-Assisted Engineering](/ai-development/), the hub that collects every essay and field note in one place. Start there if you want the map.
- [How AI Is Changing Software Engineering](/2026/05/27/how-ai-is-changing-software-engineering/), the field report on where the bottleneck moved.
- [An AI Agent Workflow for Software Engineers](/2026/06/02/ai-agent-workflow-for-software-engineers/), the core loop in full.
- [Agentic AI Development: How to Build Software with AI Agent Workflows](/2026/05/30/agentic-ai-development-workflows/), the cornerstone on giving an agent real repository access and directing it.
- [DevOps Beyond Automation](/2026/05/27/devops-beyond-automation/), what compounds across a long engineering career.
- [AgentSpek](/books/agentspek/), my book on building this way, free to start reading here.

All of this is the practical application of one larger idea I keep coming back to, [making complexity visible](/making-complexity-visible/): keeping a system understandable enough to navigate without pretending it is small. AI-assisted engineering is where I apply it every day.

## 13. A note on the meta

I built this manual the way it tells you to build software. I specified it, delegated the draft to an agent in the exact agent mode described above, verified every command against the live tools, and recorded the decisions as I went. The document is an instance of its own method. That is the meta.

The meta of the meta is the memory file. The `CLAUDE.md` and the voice rules that governed how this got written are the same kind of standing intent section 4 tells you to keep, pointed at prose instead of code. The thing that shaped the writing is itself a project memory file.

And the Übermeta, with the umlaut it has earned: the method applies to itself, all the way up. Building the thing, writing about building the thing, and setting the rules for how that writing is done are one loop running at three heights. This is [Recursive DevOps](/2026/06/05/recursive-devops/) pointed at language. The system that makes the work and the system that improves the system are the same system. Once you see it you do not unsee it. Good. Now go build something.

## Appendix A: A starter memory file

Drop this at the repo root as `CLAUDE.md` for Claude Code, and as `.github/copilot-instructions.md` for Copilot agent mode. Same content, both files. Fill in the brackets. Keep it short and true; a file that lies to the agent is worse than no file.

```markdown
# Project Memory

## What this is
[One or two sentences. What the project does, who uses it.]

## How it is built and run
- Install: [command]
- Dev: [command]
- Test: [command]
- Build: [command]

## Conventions that matter
- [The naming, structure, or style rules you actually enforce.]
- [How errors are handled here.]
- [Anything a newcomer always gets wrong.]

## Do not touch without care
- [Files or systems that are load-bearing and easy to break.]
- [The rule for changing them.]

## Lessons (append as you go)
- [Mistakes the agent made, so it stops repeating them.]
```

## Appendix B: Spec and ADR templates

Two more good ideas worth keeping as templates. The first is for the Specify step: write the intent before you prompt. The second is the ADR I keep one of per real decision.

A spec you hand the agent:

```markdown
# Intent: [one-line outcome]

## Outcome
[What is true when this is done.]

## Constraints
- [What it must not break.]
- [What it must stay compatible with.]

## Non-negotiable
- [The parts there is no flexibility on.]

## Done when
- [The check that proves it works: behavior, not exit code.]
```

An ADR you write when you decide something real:

```markdown
# ADR-[NNN]: [the decision in a few words]

**Status:** [Proposed | Accepted | Superseded]
**Date:** [YYYY-MM-DD]

## Context
[The situation that forced a choice.]

## Decision
[What we are doing, in plain language.]

## Consequences
[What this makes easy, what it makes hard, what we gave up.]
```

## Appendix C: Command cheat-sheet

The commands from this manual in one place. Terminal commands are for Claude Code; the slash commands run inside a session.

```bash
# Start and choose a model
claude                          # interactive session in the current repo
claude --model sonnet           # start on Sonnet (default for daily work)
claude --model opus             # start on Opus (hard reasoning)

# Pick up past work
claude --continue               # resume the most recent session here
claude --resume                 # choose from past sessions

# Headless, for scripts and pipes
claude -p "one-shot prompt"     # run once and exit
cat file.log | claude -p "..."  # pipe input in

# Parallel agents via git worktrees
git worktree add ../proj-x -b feature-x
git worktree list
git worktree remove ../proj-x
```

```text
# Inside a session
/model opus | /model sonnet     # switch model mid-task
/context                        # what is filling the context window
/clear                          # wipe conversation, keep the memory file
/compact                        # summarize and continue
/init                           # generate a starter CLAUDE.md
/memory                         # show loaded memory files
/agents                         # configure subagents
Shift+Tab                       # cycle permission modes (ask / auto-edit / plan)
Esc                             # interrupt a run that is going wrong
```

## About this document

Written by Joshua Ayson, a DevOps engineering leader who builds this way every day. Corrections and better tips are welcome; like the HOWTOs I learned from, this one gets revised.

- *Revision 1.0, June 2026.* First cut: setup, the loop, tips, failure modes.
- *Revision 1.1, June 2026.* Added the tools I actually use (Claude Code and Copilot agent mode), the memory-file split, context and token management, verified commands, and a cheat-sheet.

If it saved you an afternoon, it did its job.]]></content:encoded>
      <pubDate>Sat, 06 Jun 2026 17:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/06/ai-assisted-engineering-howto/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/ai-assisted-engineering-howto.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>The Cognitive Cost of Modern Software Engineering</title>
      <link>https://joshuaayson.com/2026/06/05/the-cognitive-cost-of-modern-software-engineering/</link>
      <description>AI took the typing, and the cost of software engineering did not go away. It moved from the hands to the head and got heavier. The new scarce resource is your attention, and the new discipline is managing it.</description>
      <content:encoded><![CDATA[# The Cognitive Cost of Modern Software Engineering

*AI took the typing, and the cost of building software did not go away. It moved, from the hands to the head, and on the way it got heavier. The work is more productive than it has ever been and more tiring than it has ever been, and those two facts are the same fact. This is the part the pitch leaves out.*

The story everyone tells about AI and software engineering is a story about speed. The code writes itself. A month of work becomes an afternoon. That story is true, and I have lived it, and it is the most misleading version of what happened, because it implies the work got easier. It did not get easier. It got more concentrated, and concentration has a price that you pay with your mind, all day, without the breaks the old work used to give you for free.

I want to describe that price plainly, because I have not seen many people name it, and because naming it is the first step to managing it. The companion to this is [Agent Mode Changes the Shape of Thought](/2026/06/05/agent-mode-changes-the-shape-of-thought/), which is about the opportunity. This one is about what the opportunity costs you, and it is not a small thing.

## The bottleneck moved, and so did the cost

I have said elsewhere, in [how AI is changing software engineering](/2026/05/27/how-ai-is-changing-software-engineering/), that the headline is short: AI did not replace engineers, it moved the bottleneck. The cost of writing code dropped to near zero, and the cost of deciding what to build, how to architect it, and when to ship became the whole job.

Follow that one step further than the productivity articles do. If the bottleneck moved, the cost moved with it. The work did not lose its weight. The weight relocated. It used to sit in your hands and your hours, in the sheer volume of typing and stitching and translating that a week of building required. Now it sits in your head, in the unbroken sequence of decisions that is all that remains when the typing is gone. And the head is a more expensive place to spend than the hands, because the hands can work while the mind rests, and the mind cannot rest while it is the only thing working.

That is the whole essay in one sentence, but the sentence stays abstract until you have felt the specific ways the cost shows up. So let me be concrete about them.

## Typing was a kind of rest

Here is the thing I did not understand until it was gone. The mechanical part of programming, the part that AI took, was never the hard part, and everyone knew that. What I did not expect is that it was also a kind of rest.

For most of my career a real share of a working week was typing. Boilerplate. Translating a clear idea into a verbose language. Wiring API responses together. Writing the tests that exercise the mechanical paths through code I had just written. Updating the documentation after the refactor. None of that was where the engineering lived. But it was where the day had its valleys. After you made the hard decision, you got to spend an hour or two simply executing it, and the executing was a place the mind could idle. You were producing real work and recovering at the same time. The hands moved and the deeper part of you got to coast.

Take that away and the valleys disappear. The day becomes a ridgeline. Decision after decision, with no flat stretch in between, because the flat stretches were exactly the parts the agent now does in seconds. I describe what I want, and before I have finished my coffee the change is back and it needs a judgment from me. There is no longer an hour of mechanical typing to hide inside while my mind catches its breath. The breath-catching has to be scheduled now, deliberately, because the work will not hand it to you the way it used to.

This is not nostalgia for boilerplate. I do not miss the typing. I am pointing at a real ergonomic fact that the productivity framing erases: the old work had built-in recovery, and the new work does not, and if you do not replace that recovery on purpose you will run yourself down at a rate the old job could not have managed.

## What is left is judgment, and judgment is expensive

When the typing goes, what remains is louder, and all of it is the costly kind of work.

I read more code now than I ever have, and most of it I did not write. Reading code was once maybe a tenth of the job. It is closer to two thirds of mine now: absorbing an unfamiliar stretch the agent just produced, deciding whether it is correct, whether the error handling is right, whether it interacts cleanly with the rest of the system, whether it quietly made an architectural choice while I was looking away. Reading is more tiring than writing, because writing your own code carries you forward on your own intent, and reading someone else's, even a machine's, means reconstructing an intent from the outside and checking it against what you actually wanted. You are doing that, at speed, all day.

Deciding what to build is now the front of the work instead of the preface to it. A model will build the wrong thing beautifully and fast, and the cost of a wrong decision used to be amortized across the weeks it took to implement. Now the wrong thing arrives in an afternoon, fully formed, and you either live with it or back it out. The pressure on the quality of your specification, on knowing what you actually want before the machine commits you to a polished version of a guess, is constant and it does not relent.

And there is a decision that barely existed before and is now one of the most important and most draining: knowing when to stop the agent. Agents do not get tired and they do not stop. They will refactor what did not need refactoring, scaffold for problems you do not have, keep going confidently past the point where they should have asked. The discipline to interrupt, redirect, and reject is the new craft, and restraint is the most expensive new failure mode, because the temptation to do more, faster, simply because you can, is always right there, and saying no to it dozens of times a day is its own kind of fatigue.

None of these are the parts of engineering that let your mind coast. They are the parts that demand all of it. The job did not get smaller. It got distilled down to nothing but its hardest fraction, and then you do that fraction continuously.

## The new failure mode is overload, not slowness

For my whole career the limiting factor was throughput. You could only produce so much in a day, and the failure mode was being too slow: the project that took too long, the backlog that grew faster than you could burn it down.

That failure mode is mostly gone, and a stranger one took its place. When a two-week project ships in two days, the obvious move is to run ten of them at once across the same calendar, because you can. I have done exactly this. And it does not give you more leisure. It gives you ten times the judgment to supply, ten streams to keep coherent, ten contexts to hold and switch between, ten places where a confident mistake can slip through because your attention was on stream seven when stream three went wrong.

The bottleneck is no longer how fast you can produce. It is how much you can hold without losing the thread. That is a cognitive limit, not a physical one, and it is a real ceiling. Past a certain number of live streams the coherence starts to fray, you stop catching the thing heading the wrong direction, and the very capability that let you take on ten projects becomes the reason all ten degrade at once. The new way to fail is not to be too slow. It is to take on more than one mind can keep clear, at the exact speed that makes that easy to do without noticing.

## The intensity is real, and it has a body

I do not want to keep this abstract, because the cost is not abstract. I lived its sharpest version in a stretch I wrote about as [six weeks living at machine speed](/2025/07/22/the-multithreaded-mind-six-weeks-living-at-machine-speed/).

In those weeks time stopped behaving normally. I wrote in my journal that a single month felt like a year. The line between my own thinking and the machine's processing mostly stopped existing. I was meeting more frameworks and systems in a week than I used to read about in a year, all of it at once, none of it letting up. My computer ran hot from the load, and that heat was a fair picture of what was happening inside my head. I wrote, plainly, that working with a partner all day, whether human or not, is tiring. The tiredness came with a charge to it, and both things were true. We were building about as fast as I could think, and thinking that fast for that long has a cost your body will eventually present to you.

The part I want to flag is what happened to rest. When you can make an idea real about as fast as you have it, sleep starts to feel like an interruption. I have the timestamps to prove it: Thursday 2am commits, Friday 4am pushes, weekend marathons, not because anything forced me but because I could not put it down. That is the seductive shape of this work. It does not exhaust you against your will. It exhausts you with your full enthusiastic cooperation, because the loop between idea and result got so tight and so rewarding that stepping out of it feels like loss. The old job protected you a little by being slow. This one removes the protection and replaces it with a thrill, and a thrill is not a substitute for sleep no matter how convincing it is at 3am.

## The scarce resource is now you

Put all of it together and the conclusion is uncomfortable and clarifying at once. The scarce resource in modern software engineering is no longer compute, or time, or the supply of people who can type the code. It is your own attention, your clarity, the amount of context you can hold at once without it going blurry.

Picture it as a loom. The parallel [threads of work you run at once](/2026/01/28/on-threads/) are exactly that, threads, and a thread on its own is just a loose strand. Attention is the frame that holds the threads in tension and turns them into a fabric instead of a tangle. The weave is only ever as good as the loom, and a loom has a width. Run more threads than it can hold and they slacken and cross, and the pattern you were making comes apart in your hands. The machine can spin thread faster than anyone ever has. What it cannot do is widen your loom. That part is fixed, it is yours, and everything you make is woven on it.

The machine took over the part that scaled with hours, and handed back the part that scales with the quality and the freshness of your mind. Which means your mind is now the constraint on everything, and a constraint is something you have to manage deliberately or it manages you.

This reframes what it means to be good at this job. It is no longer mainly about how much you can produce, because production is cheap. It is about how well you can protect and direct the one input that is now scarce. The most productive thing I can do on a given day is often not to open another stream. It is to keep my head clear enough that the streams I already have get real judgment instead of a tired approximation of it. That is a sentence I would have found ridiculous a few years ago, when the obvious path to more output was more hours. The path to more output now runs through a rested, clear, undivided mind, and that mind is finite in a way that the old bottleneck never made you confront.

## How you pay it down

So the discipline that this era actually demands is not a new framework or a faster tool. It is the management of your own cognition as the scarce resource it has become, and most of it is unglamorous.

The first move is legibility. The thing that overwhelms you is not the size of the system, it is the system being illegible, too tangled to hold in your head, so that every decision costs more than it should because you have to reconstruct the whole shape before you can reason about a part of it. The defense is to keep the system understandable on purpose, to spend real effort making the complex thing simple enough to reason about, which is the larger idea underneath everything I build, the practice of [making a complex system legible enough to live inside](/coherent-complexity/). A legible system is cheap to think about. An illegible one taxes you on every single move, and the tax compounds.

The second move is restraint, which I have already named as the new craft and will name again because it is that important. Not every project that can be run should be run. Not every refactor the agent offers should be taken. The capacity to do more is not a reason to do more, and the engineers who burn out fastest in this era will not be the ones who could not keep up. They will be the ones who could, and did not know where to stop. Saying no to your own capability is now a core professional skill.

The third move is to treat rest as part of the work rather than a failure of it. The old job built recovery into the day and you could afford to be careless about it. This one does not, so you have to put it back deliberately, and you have to defend it against the thrill that tells you the loop is too good to leave. Sleep is not an interruption of the work. It is the maintenance of the only instrument the work now depends on. I came to this the hard way, and it is the same antifragile instinct I try to apply everywhere, that a little structure and a little protection on the downside is what lets a system, or a person, [gain from intensity instead of being broken by it](/2026/05/30/living-with-antifragility/).

The last move is to know your own limit, the number of live streams past which your coherence frays, and to stop short of it on purpose. That number is real, it is personal, and it is lower than your ambition wants it to be. Finding it and respecting it is the difference between using this capability for a long time and using it brilliantly for a while and then crashing.

There is a practical version of all of this that I had to learn by hand: protect blocks of single-threaded attention on purpose, where you run one stream and let the loom hold a single clean pattern instead of a dozen fraying ones. The instinct of the era is to parallelize everything, because you can, and some of the most valuable work I do now is the deliberate refusal to, the hour given over to one hard problem with my whole undivided head. The machine made breadth cheap. Depth stayed expensive, and depth is still where the hard decisions get made well.

## The work got more human, not less

There is a fear that AI hollows out engineering, turns it into prompting, removes the craft. My experience is close to the opposite, and the cost is the proof. The machine took the parts that were mechanical, the typing and the translation, the parts that were never really you. What it left behind is the parts that are nothing but you: the taste to know what is worth building, the judgment to know when something that looks right is wrong, the clarity to hold a complex thing in your head, the restraint to stop. Those parts are expensive precisely because they are human, and they cannot be delegated, and there is now nowhere to hide from them inside an afternoon of comfortable typing.

That is why the work is more tiring even as it is more productive. You are spending the whole day in the part of yourself that costs the most to spend. The bargain is real and it is good, but it is a bargain, and pretending it is free is how people get hurt by it. Name the cost, manage the resource, protect the mind, and you can do this for a long time and love it. Ignore the cost because the productivity numbers are intoxicating, and the resource that the whole thing depends on, which is now you, will run out, quietly, at the exact moment you are most convinced you are invincible.

If you want the method I run inside all of this, it is the [book-length version in AgentSpek](/books/agentspek/), free here, and the rest of how I build this way lives at [AI-Assisted Development](/ai-development/). The day-to-day shape of the bargain, where the hours actually go from the senior seat, is in [How I Use AI as a Senior Engineer](/2026/06/12/how-i-use-ai-as-a-senior-engineer/). But the most important tool is not in any of them. It is the discipline of guarding the one resource that does not scale, and that, unlike the typing, no machine is going to take off your hands.]]></content:encoded>
      <pubDate>Fri, 05 Jun 2026 22:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/05/the-cognitive-cost-of-modern-software-engineering/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/the-cognitive-cost-of-modern-software-engineering-hero.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>Recursive DevOps</title>
      <link>https://joshuaayson.com/2026/06/05/recursive-devops/</link>
      <description>DevOps was always a feedback loop. The first one ran between people. The one worth building now runs the system back on itself, so every failure and every change makes the next one cheaper and safer. The recursion is the compounding.</description>
      <content:encoded><![CDATA[# Recursive DevOps

*DevOps was always a feedback loop. The first version of it ran between people. The version worth building now runs the system back on itself, so that every failure and every change feeds forward into a system that is cheaper and safer to change next time. The recursion is the whole compounding mechanism, and most teams never turn it on.*

The longer I work inside the DevOps thesis, the more I think the original idea was both completely right and quietly mislabeled. It got remembered as a thesis about automation. It was really a thesis about loops. And once you see it as a thesis about loops, an obvious question appears that the industry mostly did not ask: a loop between what and what, and how many times does it run.

This is the answer I have arrived at. The most valuable thing you can do in operations is not to automate the work. It is to close the loop on the system itself, so the system becomes the thing that improves the system. I have written the broad version of why systems thinking is the part that compounds in [DevOps Beyond Automation](/2026/05/27/devops-beyond-automation/). This is the narrower, sharper claim underneath it.

## The loop was the original idea

The original DevOps argument was simple and correct. Developers and operators were optimizing against each other, the friction between them was the single largest source of incidents, and the cure was to put them in the same loop. Deploy small changes often. Automate the path from commit to production. Measure what matters. Share responsibility for the running system, not just the code that produced it.

Every word of that is still true. But notice the shape of it. The cure was not a tool. The cure was a feedback loop. Put the people who write the change and the people who run the change into one circuit, so that the consequences of a decision reach the person who made it, quickly, while they can still do something about it. That is the actual invention. The pipelines and the dashboards and the alerting were just the wiring that made the loop fast.

When you see the loop as the invention, the tools stop being the point. A loop is a pattern, and a pattern can be applied to more than the thing it was discovered on. The first DevOps loop closed between two groups of humans. The interesting move is to ask what else you can put inside a loop, and what happens when the loop starts feeding into the very thing that produced it.

## From a loop between people to a loop on the system

Here is the shift. The original loop ran from the system to a human and back: the system did something, a human saw it, the human changed the system. That is already valuable, and it is most of what teams build. But the human in the middle is a bottleneck, and more to the point, the human keeps having to learn the same lesson because nothing about the system itself changed to remember it.

A recursive loop closes the circuit one level deeper. The system does something, a human sees it, and then the human changes the system so that the system itself now handles that case, or makes it impossible, or surfaces it earlier next time. The output of one pass is a permanent change to the thing that will run the next pass. The loop is no longer just operating the system. It is reshaping it, and each reshape changes what the next reshape starts from.

That is what I mean by recursive DevOps. Not infinite cleverness. A discipline of always closing the loop one level deeper than the incident, so that the work you do this week lowers the cost or the risk of the work you do next week. If your operational effort this month did not make next month's operational effort cheaper, you did maintenance. Maintenance is necessary, but it does not compound, and the whole game in a long-lived system is compounding.

## A failure is an input, not the enemy

The cleanest example I have is the day an agent-written deploy script deleted most of production.

The script was good. It built the site, synced the files to a bucket, and cleaned up anything stale so the live state matched the build exactly. That last behavior, deleting whatever was not in the new build, is correct right up until the build comes up short. One day a build failed partway through, produced an incomplete set of files, and the script did exactly what it had been told. It made the live site match the incomplete build, which meant deleting most of the images from production. I have written the longer version of this in [how I rebuilt this site in agent mode](/2026/06/03/rebuilt-my-site-in-agent-mode/), but the part that matters here is what I did with the failure.

The non-recursive response would have been to fix the immediate problem. Re-upload the images, clear the cache, move on, and add a line to a runbook telling the next person to be careful. That closes the loop at the human level. The lesson lives in a person, the system is exactly as dangerous as it was, and the failure is waiting to happen again to someone who has not read the runbook.

The recursive response is to change the system so the failure cannot recur. I pushed the images back with a sync that only adds and never deletes, and then I changed the deploy itself so that a bad build can no longer reach a destructive step, and so asset uploads only ever add. The failure became a permanent improvement to the shape of the system. The system now knows something it did not know before, not in a document, in its structure. That is the only good thing a failure is for, and a failure that you spend on a runbook line instead of on the architecture is a failure you have agreed to suffer again.

This is what people mean, or should mean, by antifragile, and it is the same instinct I try to bring to everything I build, the practice of [making systems that gain from disorder](/2026/05/30/living-with-antifragility/) rather than ones that merely survive it. A robust system takes the hit and stays standing. A recursive system takes the hit and comes out the other side unable to take that particular hit again. The disorder is not the thing you are defending against. It is the input. Every incident is a free piece of information about where your system is weak, paid for in pain you have already spent. The only waste is to spend the pain and not collect the information.

The discipline that makes this routine is naming failure modes before they happen and rehearsing them. The platform itself keeps teaching me to do it: assume the part will fail, decide in advance what happens when it does, and build so that the answer is already known. What happens when a deploy is incomplete. What happens when a cache header is wrong. What happens when a path that worked on the old host does not resolve on the new one. Each of those questions, asked early, is a small recursion run on purpose instead of waiting for the system to run it on you at three in the morning.

## Make the runbook unnecessary

There is a tell that separates teams that are looping recursively from teams that are just automating, and it is the runbook.

Automation looks at a nine-page runbook and asks how to execute it faster. It writes the script that runs the steps. This feels like progress, and it produces real, measurable savings, and it is the easy half of the job. The hard half, the recursive half, looks at the same nine-page runbook and asks a different question: why does this need to exist at all? A system that requires fifteen humans to interpret seven dashboards to decide whether it is safe to deploy on a Friday is not a system that needs more automation. It is a system that needs a different shape. Automation built on top of a confused architecture just amplifies the confusion at higher speed.

I have written a lot of runbooks. The work that actually moved the incident rate down was almost never the runbook. It was the work that made the runbook unnecessary. The runbook is the symptom. The architecture that produced it is the disease, and you can spend a career treating symptoms very efficiently while the disease compounds underneath.

So the recursive move on any piece of operational toil is to ask whether this pass eliminates the need for the next pass, or merely speeds it up. Automating a manual step that should not exist is a local optimum that locks in the thing you should have removed. The deeper version of the question, the one that pays off over years, is the one most organizations are bad at, because they are exquisitely good at calculating the cost of doing something and catastrophically bad at calculating the cost of not doing it. The five-year-old instance nobody will touch because nobody knows what runs on it is a cost. The fragile deploy everyone is afraid to refactor is a cost. The migration the team has spent four years not doing is a cost. Automation does not surface those. Only judgment does, and judgment is the part of this that does not get automated, which is exactly why it is the part that keeps mattering.

## The platform that improves the platform

Around 2022 the industry started calling the mature version of this platform engineering, and the rename was useful because it made the recursion explicit. The platform is a product. The application teams are the customers. And the platform team's entire mandate, the whole of it, is to make the next line of application code easier and safer to ship than the previous one.

Read that mandate as a function and it is openly recursive. Each thing the platform team ships is supposed to lower the cost of the next thing everyone else ships, which lowers the cost of the thing after that. A platform feature that nobody adopts is not neutral. It is debt, because it added surface area without lowering anyone's cost of change. The platform team's success is not measured by how much they ship. It is measured by how much the application teams ship because the platform exists. That is a derivative, a rate of change of someone else's velocity, and optimizing a derivative is a fundamentally different posture than optimizing your own output.

This is the recursion at the organizational scale. You are not building the product. You are building the thing that builds the product, and then improving the thing that builds the thing, and the payoff lives in how many downstream changes each upstream change makes cheaper. A team that internalizes this stops measuring itself by tickets closed and starts measuring itself by friction removed, which is the only metric that compounds.

## Agent mode closes the loop faster

Everything above was true before AI agents entered the workflow. What agent mode changes is the cost of a single pass through the loop, and lowering that cost changes how often you can afford to run the recursion.

A lot of the routine platform work that used to take a junior engineer a week now takes a senior engineer a morning. Writing the Terraform module, [scaffolding the service](/2026/06/03/microservices-agents-what-im-building-next/), generating the CI workflow, drafting the runbook, and crucially, performing the reshape that makes the runbook unnecessary: all of that compresses hard. When the mechanical cost of changing the system drops toward zero, the recursion gets cheaper to run, and things that were too expensive to bother fixing become worth fixing. The half-day refactor that removes a class of incident was never worth a week of a person's time against everything else on the board. At a morning, it is obviously worth it. So the loop runs more often, and a loop that runs more often compounds faster.

The economics of the team shift with it. The old question was how many junior engineers you needed to do the rote work. The new question is how many senior engineers you need to direct the rote work the agents now do, and the ratio inverts. A platform team stops being measured by its capacity to produce configuration and starts being measured by the quality of its judgment about which configuration is worth producing. That is a smaller team doing higher-altitude work, and it is only an improvement if the judgment is actually there. Invert the ratio without the systems literacy to aim the agents and you have not made the team better. You have given it a faster way to generate operational debt, because the agents will widen whatever loop you point them at, the compounding one or the destructive one, with equal cheerfulness.

But there is a sharp edge, and it is the same edge I described in [Agent Mode Changes the Shape of Thought](/2026/06/05/agent-mode-changes-the-shape-of-thought/). The agents are very good at the steps and very bad at whether the steps are the right steps. An agent will happily build a beautifully clean pipeline that solves the wrong problem. It will write a Terraform module that provisions infrastructure your team cannot operate. It will refactor a deploy script in a way that breaks a tribal-knowledge invariant nobody wrote down. This is not a flaw in the agents. It is a clarification of where the engineering always was. The agents have made it impossible to fake the systems-thinking part of the job, because they will produce an enormous volume of confident, plausible work that quietly increases the operational debt if a real judgment is not steering it.

So agent mode does not run the recursion for you. It turns the crank. It makes each pass cheap. The thing that decides whether the loop compounds or just produces more system faster is still a human deciding which failure is worth turning into a permanent improvement, which change actually lowers the cost of the next change, and which part of the system to point the loop at next. The agent makes the reshape cheap. It cannot tell you that the reshape was worth doing, or that you reshaped the right thing.

## Pointing the recursion

The practical version of all of this fits on one question, which I now ask of nearly every piece of operational work: does this pass make the next pass cheaper, or does it just get me through today?

If it gets me through today, it is maintenance, and sometimes maintenance is what the day requires. But if I find that almost everything I am doing is getting me through today, I am running an open loop. I am operating the system and learning nothing into it. The recursive habit is to spend a fixed fraction of every incident and every change on [closing the loop one level deeper than the problem in front of me](/2026/06/13/how-to-detect-ai-writing-tells/). The incident becomes a structural change that makes it impossible. The change becomes a lowering of the cost of the next change. The runbook becomes an architecture that needs no runbook.

The signals that tell you whether the recursion is working are the boring operational numbers, and they are honest in the way that physics is honest. I have written about how [AWS is math and Kubernetes is physics](/2026/05/31/aws-is-math-kubernetes-is-physics/), how one discipline bills you in money and the other in latency and contention. Those bills are the feedback. The cost trend, the incident rate, the time it takes a new engineer to ship safely, the length of the runbook: those are the readouts of whether each pass is making the system cheaper to change or more expensive. A recursive practice bends them in the right direction over quarters, not because of any single heroic fix, but because the loop is pointed at making the next thing easier, and it keeps running.

## The system that gets stronger from what hits it

DevOps started as a loop between people, and that was the right place to start, because the friction between people was the first bottleneck. The version I am describing is the same idea taken one level deeper: a loop the system runs on itself, with a human pointing it and agents turning the crank fast enough that you can afford to run it constantly. The output of the loop is not a deployment. The output of the loop is a better system for producing the next deployment, and a better system again after that.

The aim, in the end, is a system that gets stronger from what hits it. Not one that resists disorder, but one that converts it, that takes every failure and every awkward change and every painful migration and comes out structurally improved, unable to suffer that exact thing again, cheaper to change than it was the day before. That requires keeping the whole growing thing legible enough to actually reason about, which is the larger idea underneath everything I build, the practice of [making a complex system legible enough to live inside](/coherent-complexity/), whether the system is a cloud platform, a codebase, or [a life](/2026/06/02/life-ops-running-your-life-like-software/). The agents will turn the crank as fast as you let them. Whether the loop compounds is the part that is still, and will remain, yours.

One small, daily instance of this loop is having one agent review another's work, the adversarial second pass I describe in [My AI Code Review Workflow](/2026/06/11/ai-code-review-workflow/): cheap to run, and a place where the recursion earns its keep before any of it ships.

If you want the broader argument for why systems literacy is the skill that survives, it is in [DevOps Beyond Automation](/2026/05/27/devops-beyond-automation/), and the book-length version of how I work this way is [AgentSpek](/books/agentspek/), free to start reading here. The rest of how I build lives at [AI-Assisted Development](/ai-development/).]]></content:encoded>
      <pubDate>Fri, 05 Jun 2026 21:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/05/recursive-devops/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/recursive-devops-hero.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>Agent Mode Changes the Shape of Thought</title>
      <link>https://joshuaayson.com/2026/06/05/agent-mode-changes-the-shape-of-thought/</link>
      <description>Agent mode is not a faster way to type. It moves the unit of thought up from syntax to intent, turns you into a conductor of parallel work, and makes the real bottleneck the clarity you can hold in your head at once.</description>
      <content:encoded><![CDATA[# Agent Mode Changes the Shape of Thought

*The speed story is the easy one to tell and the least interesting. What actually changes when you build software in agent mode is the unit you think in, the number of things you can hold at once, and where the hard part of the work goes to live.*

When people describe agent mode, they almost always reach for speed. It writes the code faster. It does in an afternoon what used to take a month of evenings. That is true. I have said it myself. And it is the shallow version, because it measures a new thing with the old ruler.

The deeper change is harder to see, because it happens inside your head instead of on the screen. What I keep noticing is not that I produce more. It is that I think differently. The shape of the work changed. The unit I reason in moved up a level. The number of things I can hold in flight went up with it. And the part of the job that is actually hard relocated to a place it never used to live.

This is an attempt to describe that change plainly, from the inside.

## First, the plain definition

If you have not used it, here is the short version. I wrote a [longer one separately](/2026/06/02/what-is-agent-mode/). Agent mode is when you stop typing code and start directing an AI that reads your codebase, makes the change across as many files as the task needs, runs the tests, and reports back. You describe the outcome. It does the work and checks itself. You review, correct, and send it again.

The loop is not write, compile, test. It is specify, generate, verify, specify. You say what you want clearly enough that an agent can act on it. It produces the change. You confirm the result is right, or you catch that it is wrong. Then you correct course and go again.

Notice where the hours go in that loop. Not into typing. They go into the first step and the third: being precise about what you want, and checking that you got it. Hold onto that, because everything that follows comes out of it.

## The unit of thought moves up

For most of the history of programming, the unit of thought was small. You held a function in your head. You held the line you were typing, the variable you were tracking, the bug three calls down the stack. Even with good autocomplete the unit did not really change. Autocomplete finishes the line you are already writing. You are still the one holding the whole task in your head, typing it out one suggestion at a time. The machine is a faster keyboard, not a different altitude.

Agent mode moves the altitude. I am no longer working at the level of the keystroke, or even the function. I am working at the level of the task, and increasingly at [the level of the system](/2026/06/03/microservices-agents-what-im-building-next/). I do not think "write a loop that does this." I think "this endpoint needs rate limiting and the tests need to cover the new failure case," and that sentence is the work. The agent reads the relevant files, writes the change, runs the suite, and comes back with a diff. I was never in the editor. I was holding the intent.

That shift sounds small and it is not. When the unit of thought is a function, your day is a thousand tiny acts of translation: turning what you want into the exact syntax that produces it. When the unit of thought is a task, that translation layer mostly disappears, and what is left is the thinking it used to bury. You spend your attention deciding what should exist and whether what came back is correct. The grammar stops being the bottleneck. The idea becomes the bottleneck, which is where it belongs.

I noticed this most clearly the first time I described an outcome instead of a procedure. I needed to stand up an AWS service behind CloudFront with a private S3 origin and a password gate at the edge. The old way was to read the documentation, write the infrastructure code, wire the origin access control, debug the bucket policy, fix the cache behavior, and repeat until it held. In agent mode I described the end state: private bucket, served only through this one distribution, gated by a password at the edge. The agent wrote the configuration, explained the wiring, and flagged the single gotcha that breaks these setups. My job was to decide the design and verify the result, not to remember the order of the arguments. The cost of writing the configuration dropped to almost nothing. The cost of deciding what to build and confirming it was right became the entire job.

## The bottleneck moves off your hands

This is the part the hype skips. Working in agent mode is not less engineering. It is more of the engineering that matters and less of the typing that does not.

For years the limiting factor on what one person could build was production. There were only so many hours, and the hours went into making the thing. Agent mode takes the cost of making the thing and drives it toward zero. What is left is what was always the real job and was always crowded out by the typing: knowing what to build, and knowing when something that looks right is actually wrong.

So the bottleneck moved. It used to sit in your hands, in how fast and how long you could produce. Now it sits in two places, and both are upstream of any code. The first is the clarity of your intent. Vague intent produces a polished version of the wrong thing, fast, so the act of being precise about what you want is no longer a preface to the work. It is the work. The second is the rigor of your verification. AI-generated code can pass every test you wrote and still be wrong, because it can satisfy the letter of a specification while missing the thing you actually meant. So checking is not a formality at the end. It is half the job, and it does not get easier as the production gets faster. If anything it gets harder, because there is more output arriving and less of it passed through your own hands on the way.

When I [rebuilt this site in agent mode](/2026/06/03/rebuilt-my-site-in-agent-mode/) and moved it off shared hosting onto AWS, that is exactly where my attention went. I was not writing the components or the deploy configuration. I was deciding what the site should be, reading the diffs, catching the architectural choices that would cost me later, and saying yes or no. The thing that did not drop, the thing that became more important than before, was judgment.

## Scaling cognition, not output

The part that still surprises me is what happens when it is not one agent but several.

With one agent you are a person directing a fast collaborator. With several you become something closer to a conductor. One agent is refactoring a module while another drafts a migration while a third checks a result. You are holding more in flight than a single human working alone could hold, and the holding is the skill. The bottleneck moves off your hands entirely and onto your ability to keep several streams coherent at once: to know which one needs you now, to feel when one is confidently heading the wrong direction, to keep the whole shape in your head while the pieces move.

This is where I am most willing to say something strong, because it is the thing I did not expect. This is genuinely a new way to think, not just a new way to type. You are scaling your own cognition. And the limit is no longer how fast your hands move or how many hours you have. The limit is how much clear intent you can hold at one time. That is a cognitive limit, not a physical one, and it is trainable in a way that typing speed never really was.

I keep coming back to the [Iron Man suit](/2026/06/03/agent-mode-iron-man-suit/) as the closest image, because the suit never replaced the man inside it. It amplified him. Without the man it is an empty shell, and without the suit the man is just very smart in a cave. The whole point is the pairing. And the suit does not make Tony Stark a faster typist. It makes his intent reach further. He decides where to go, and the machine handles the flying. What changes is not the speed of his hands. It is the radius of what one person can affect, and the radius is set by the clarity of the person at the center.

## The proof is the range

Here is the evidence, and it is not a benchmark. Over the last year I shipped four open-source projects, each in a different domain. A library of small playable games. A music synthesis engine built from raw arrays of numbers, with no samples. An animation studio that runs from scripts. A language-learning system that is nothing but text files and prompts. Different fields, different skills, none of which I am formally trained in across the board, all built primarily in agent mode, and all shipping things you can actually use today.

A few years ago that range would have been impossible for one person in a year. Not because the individual pieces are beyond a determined builder, but because the cost of becoming fluent enough in four unfamiliar domains to produce finished work in each one was too high. The typing alone would have eaten the year. What collapsed that cost was not that the agent knew those domains for me. It was that the agent handled the translation in each one, the part where you turn a clear intent into the specific incantation that a synthesizer or an animation pipeline or a spaced-repetition system wants. So my actual job in all four was the same job: decide what should exist, set the constraint, and verify the result.

That sameness is the tell. When the unit of thought is the keystroke, every new domain is a new language you have to learn before you can say anything in it. When the unit of thought is the intent, the domains start to rhyme, because the thing you are doing, holding a clear specification and actually checking it, does not change when the subject does. The skill that scales is not domain knowledge. It is the discipline of clear intent, and that discipline ports.

I do not think this means anyone can now do anything. Taste does not transfer for free, and a clear head in one domain is not automatically a clear head in another. But the friction that used to keep a single builder pinned to one specialty got much thinner, and what is left holding you is your own judgment, spread as wide as you can keep it coherent. The four projects, and the one philosophy underneath them, are written up [together](/projects/) if you want the longer look.

## Judgment becomes the whole job

I want to be careful here, because the same thing that makes the suit powerful is exactly how you fly it into a mountain.

It does what you point it at, fast, and confidently, and that is precisely the danger. A vague intent gets you a polished version of the wrong thing. A weak check lets a plausible mistake through at speed. The faster the system, the more your judgment is the only thing standing between you and a very efficient disaster. Power that does what you say is only as good as the clarity of what you say and the rigor of how you confirm what came back.

I learned this in the most direct way possible. An agent wrote a deploy script for this site. It was a good script. It built the site, synced the files to S3, and cleaned up anything stale so the live bucket matched the build exactly. That last behavior, deleting whatever was not in the new build, is correct right up until the build comes up short. One day a build failed partway through and produced an incomplete set of files, and the script did exactly what it had been told: it made the live site match the incomplete build, which meant deleting most of the images from production.

Nothing about that was the agent being stupid. The script was logical. The bug was that a destructive operation had been coupled to an assumption that the build was always complete, and nobody, human or machine, had questioned that assumption until it failed.

The recovery is the point. The images were never really lost, because the source of truth was the repository on my machine, not the bucket. I pushed them back with a sync that only adds and never deletes, cleared the cache, and the site was whole again in a few minutes. Then I did the thing the incident was actually asking for. I changed the deploy so a bad build can no longer reach a destructive step, and so asset uploads only ever add. The failure became a permanent improvement to the system, which is the only good thing a failure is for.

That is the loop working as intended. Trust it to do the work. Do not trust it to be right. Keep a source of truth it cannot touch, and keep the irreversible operations behind a gate. The agent did most of the typing for the original script, the recovery, and the hardening. The judgment about how it should fail was mine, and it had to be, because that is the kind of decision that does not survive being delegated.

## What this asks of you

If the production stops being the constraint, the constraint becomes you, and not in a way you can fake.

You have to actually know what you want. Agent mode is brutal about this. When my intent is clear, the work pours out and most of it is right. When my intent is muddy, the work pours out just as fast and most of it is subtly wrong, and I have to throw it away and figure out what I was actually after, which I should have done first. The tool will not do that part. If the problem is still fuzzy in your own head, no amount of delegation helps, because you cannot specify what you have not figured out. That part is still yours, and it is more exposed than it used to be, because there is nowhere to hide it. You cannot disappear into an afternoon of typing and feel productive while you avoid the hard decision. The typing is gone. The decision is all that is left.

So the discipline did not go away. It moved, and it concentrated. I spend less effort making the thing and far more effort being sure I asked for the right thing and that the thing is correct. I think in failure modes now, because the platform keeps teaching me to: assume the part will fail, name how, and build so that when it does you already know what happens next. I think in specifications, because a specification is just intent made precise enough to act on. I think in verification, because speed without checking is just a faster way to be wrong. None of those are new ideas in engineering. What is new is that they are no longer the parts you get to around to. They are the parts that are left.

There is a version of this that reads as loss, as if the craft got hollowed out. I do not experience it that way at all. The typing was never the craft. The craft was always the judgment, the taste, the decision about what is worth building and the eye for when something that looks right is wrong. Agent mode did not remove the craft. It removed everything around the craft, and left me standing in front of the part that was always the point, with my whole attention free to spend there. This is the same instinct I bring to everything else I build, the discipline of [making a complex system legible enough to live inside](/coherent-complexity/), whether the system is a cloud platform, a codebase, or [a life](/2026/06/02/life-ops-running-your-life-like-software/).

## Where it leaves you

The gap between having an idea and having the thing got small. A single builder with taste and a clear head can now reach a scale that used to require a team, and can keep the whole thing coherent because it is still one mind directing it. That is the part that feels new and a little vertiginous: the reach went up, and the thing that sets the reach is no longer your hands. It is the clarity you can hold.

So the practical advice is almost philosophical. Get clear. Learn to say what you want with enough precision that another intelligence can act on it without you hovering. Learn to verify without flinching, especially when the output looks finished. Learn to hold more than one thread without losing the shape of the whole. Those are the skills that scale now, and they are skills of thought, not skills of typing.

If you want the method I run inside all of this, I wrote down [an AI agent workflow that holds up](/2026/06/02/ai-agent-workflow-for-software-engineers/), and the book-length version is [AgentSpek](/books/agentspek/), free to start reading here. If you want the feel of the work rather than the mechanics, it is [not vibe coding](/2026/05/07/ai-assisted-development-is-not-vibe-coding/). And the rest of how I build this way lives at [AI-Assisted Development](/ai-development/).

The suit is real. It fits. And the strange, good catch is that it makes the human inside it matter more, not less, because the one thing it cannot do, decide what is worth building and know when it is right, is suddenly the only thing left to do.]]></content:encoded>
      <pubDate>Fri, 05 Jun 2026 20:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/05/agent-mode-changes-the-shape-of-thought/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/agent-mode-changes-the-shape-of-thought-hero.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>Microservices, Agents, and What I Am Building Next</title>
      <link>https://joshuaayson.com/2026/06/03/microservices-agents-what-im-building-next/</link>
      <description>Microservices used to be a tax a solo builder could not afford. AI agents change that math. Here is why I am drawn to the architecture for what I build next, and the discipline that keeps it from becoming a mess.</description>
      <content:encoded><![CDATA[For most of my career, microservices were a tax I could not afford alone. The idea is good: break a system into small, independent services, each owning one job, each able to fail, scale, and change without dragging the rest down with it. The problem was the overhead. More services means more deployments, more boundaries to define, more wiring, more ways for the connections between things to break. For a small team or a solo builder, the cost of all that machinery usually outweighed the benefit, and the answer was to keep things in one well-organized monolith and not pretend otherwise.

AI agents change that math, and that is why the architecture is back on my mind for what I build next.

## What the agents change

The tax on microservices was never really the services. It was the connective tissue: the boilerplate, the deployment pipelines, the glue code, the operational babysitting of a dozen small things instead of one big one. That is exactly the kind of work the cost of which has collapsed. An agent can stand up a service, wire its deployment, write its tests, and connect it to the rest, in the time it used to take to decide whether the effort was worth it.

When the overhead per service drops far enough, the calculus flips. The reasons to want small, independent, isolated services were always sound. It was only ever the price that made them impractical at small scale. Lower the price and a single builder can run an architecture that used to require a platform team.

There is a deeper fit, too. A microservice is, by design, a bounded piece of work small enough to hold in one head. That is also the size of work an agent handles best. An architecture made of small, clearly-bounded units is an architecture you can hand to agents one unit at a time, which means the way I want to build and the way I want to structure what I build are starting to point in the same direction.

## Why it fits how I already think

This is not a new instinct dressed in new clothes. It is the same idea I keep circling in everything else.

Breaking a system into bounded services is one more way of making a complex thing [legible instead of simple](/coherent-complexity/). You do not pretend the system is small. You give it seams, so a human, or an agent, can reason about one part without holding all of it at once. The whole stays complex; each piece becomes comprehensible. That is the entire move I care about, applied to architecture.

It is also [antifragile](/2026/05/30/living-with-antifragility/) by construction. Isolation means a failure in one service is contained instead of cascading. Redundancy and independent scaling mean the system can absorb a shock in one place and keep running everywhere else. The same logic that makes me hold slack in a portfolio and redundancy in infrastructure makes me want boundaries in a system: not to be efficient, but to survive the part that breaks.

## Robustness before optimization

Here is the catch, and it is the same catch as always. The fact that agents make microservices cheap does not make microservices free, and it absolutely does not make them always correct.

There is a failure mode where you decompose a thing into twenty services because you can, and you end up with distributed complexity that is harder to reason about than the monolith you started with. A poorly drawn boundary is worse than no boundary. Splitting a system along the wrong seams gives you all the overhead of distribution with none of the benefit, and now the mess is spread across a network instead of contained in one codebase.

So the rule I am holding onto is the same one I apply to money and to systems generally: robustness before optimization. Start with the simplest thing that works, usually one service, and split only when a real seam reveals itself, when a part genuinely wants to fail, scale, or change on its own schedule. Let the architecture earn its complexity. Do not reach for the sophisticated structure because the tools finally let you. Reach for it when the system is actually asking for it, and not one service before.

## What this means for what I build

The practical upshot is that the things I make next, the apps and tools and environments I have been sketching, get to be designed the way I always wanted them designed, in small legible pieces, because the help is finally good enough to make that practical for one person. I get to keep pushing the limits of what a single builder can stand up, using AI as additional hands, and keep the result coherent because each piece is small enough to understand and the seams between them are drawn on purpose.

That is the whole bet I keep making, in one more domain. Not simpler. Legible. A complex system, built in pieces you can actually reason about, that survives the failure of any one of them, and that one person can now hold in their head because they had the help to give it the right shape.

If you want the method underneath the building, it is [an AI agent workflow that holds up](/2026/06/02/ai-agent-workflow-for-software-engineers/). For the idea underneath the architecture, it is all the same thing: [coherent complexity](/coherent-complexity/).]]></content:encoded>
      <pubDate>Wed, 03 Jun 2026 19:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/03/microservices-agents-what-im-building-next/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/microservices-agents-what-im-building-next.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>Agent Mode Feels Like the Iron Man Suit</title>
      <link>https://joshuaayson.com/2026/06/03/agent-mode-iron-man-suit/</link>
      <description>The suit never replaced Tony Stark. It amplified him. That is the closest thing I have to a description of what it feels like to build software in agent mode, directing one or many agents and scaling your own thought and output.</description>
      <content:encoded><![CDATA[The thing about the Iron Man suit is that it never replaced Tony Stark. It amplified him. Without the man inside it the suit is an empty shell, and without the suit the man is just very smart in a cave. The whole point is the pairing. That is the closest description I have of what it feels like to build software in agent mode, and I have been chasing a better metaphor for months without finding one.

I dreamt of this for a long time before it arrived. Not the specifics. The feeling. The sense that the distance between having an idea and having the thing could collapse, that a single person with enough clarity could reach further than a single person ever has. It is here now, and it has exceeded what I let myself expect.

## What the suit actually amplifies

It is easy to assume the amplification is speed, that the suit just lets you type faster. That is the shallow version and it misses the real thing. The suit does not make you a faster typist. It makes your intent reach further. You decide where to go, and the machine handles the flying.

In practice that means I am no longer working at the level of the keystroke or even the function. I am working at the level of the task, and increasingly at the level of several tasks at once. I describe what I want built, the agent goes and builds it across the whole codebase, runs it, reads the failures, fixes them, and comes back. My attention sits where it is actually worth something: on what to build, on whether the result is right, on the decisions that compound.

The cost of producing the work dropped toward nothing. What is left is the part that was always the real job, and it turns out there is a lot of it.

## Scaling thought, not just output

The part that still surprises me is what happens when it is not one agent but several. You stop being a person who does one thing at a time and start being something closer to a conductor. One agent is refactoring a module while another is drafting a migration while a third is checking a result. You are holding more in flight than a single human working alone could hold, and the holding is the skill.

This is where the suit metaphor strains in a good way, because it stops being about a single exosuit and becomes about commanding a small fleet. The bottleneck moves off your hands and onto your ability to keep several streams coherent in your head, to know which one needs you now, to catch the one that is confidently heading the wrong direction. It is genuinely a new way to think, not just a new way to type. You are scaling your own cognition, and the limit is how much intent you can keep clear at once.

## Someone still has to fly it

I want to be careful here, because the suit is also exactly how you fly into a mountain.

It does what you point it at, fast, and confidently, and that is precisely the danger. A vague intent gets you a polished version of the wrong thing. A weak check lets a plausible mistake through at speed. The faster the suit, the more your judgment is the thing standing between you and a very efficient disaster. Power that does what you say is only as good as the clarity of what you say and the rigor of how you verify what came back.

So the discipline did not go away. It moved. I spend less effort making the thing and more effort being sure I asked for the right thing and that the thing is actually correct. That is not a downgrade. That is the work arriving at the place where a human is genuinely irreplaceable, and being freed to spend its whole attention there.

## The most alive I have felt building

I am aware this can read as hype, so let me just say the plain version. This is the most exciting time of my life to be alive and making things. Not because the tools are impressive, though they are, but because of what they do to the gap between a person and what that person can build. The gap got small. A single builder with taste and judgment and a clear head can now [reach the scale that used to require a team](/2026/06/03/microservices-agents-what-im-building-next/), and can keep the whole thing coherent because it is still one mind directing it.

The suit is real. It fits. And the strange, wonderful catch is that it makes the human inside it matter more, not less, because everything it cannot do, deciding what is worth building and knowing when it is right, is suddenly the only thing left to do.

If you want the method I run inside the suit, it is [an AI agent workflow that holds up](/2026/06/02/ai-agent-workflow-for-software-engineers/), and the book-length version is [AgentSpek](/books/agentspek/), free here. For how I keep the whole expanding system legible instead of overwhelming, that is the larger idea: [coherent complexity](/coherent-complexity/).]]></content:encoded>
      <pubDate>Wed, 03 Jun 2026 18:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/03/agent-mode-iron-man-suit/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/agent-mode-iron-man-suit.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>I Rebuilt This Whole Site in Agent Mode</title>
      <link>https://joshuaayson.com/2026/06/03/rebuilt-my-site-in-agent-mode/</link>
      <description>This site was rebuilt from scratch by directing an AI agent, then migrated off cPanel onto AWS S3 and CloudFront. Here is what that actually looked like, the parts that worked, and the day a deploy script quietly deleted production.</description>
      <content:encoded><![CDATA[The site you are reading was rebuilt from scratch by directing an AI agent, and then moved off shared hosting onto AWS. I did not type most of it. I directed it. That distinction is the whole story, so let me be concrete about what it actually looked like, because the real version is more useful than the brochure.

## The starting point was WordPress on cPanel

Before this, the site was WordPress on cPanel, the way a lot of personal sites are. It worked, in the sense that it was up. It was also slow, heavy, a moving target for security updates, and a place where every change meant fighting a theme and a stack of plugins to do something a flat file could do better. I wanted a static site: plain HTML and CSS served fast, with the content living as files I own instead of rows in a database I have to babysit.

So the goal was two things at once. Rebuild the site on a modern static stack, and migrate the hosting off cPanel and onto AWS. Either one is a project. Doing both, solo, would have been a month of evenings a couple of years ago. It was not.

## What "agent mode" actually meant here

Agent mode is letting the AI do the task, not the keystroke. I did not ask it to write a function. I handed it the codebase and a destination: build this in Astro, keep the content as markdown, make it fast, match this design sense. Then it read the existing structure, made changes across many files at once, ran the build, read the errors, and fixed them, and surfaced when it was stuck or when a real decision was mine to make.

My job moved up a level. I was not writing the components. I was deciding what the site should be, reviewing the diffs, catching the architectural choices that would cost me later, and saying yes or no. The cost of producing the code dropped close to zero. The thing that did not drop, the thing that became more important, was judgment: knowing what to build, and knowing when the agent had done something that looked right and was wrong.

That is the part the hype skips. Working this way is not less engineering. It is more of the engineering that matters and less of the typing that does not.

## The migration, and the antifragile habit

Moving from cPanel to AWS meant rebuilding the serving layer too: the site is now static files in an S3 bucket, served through a CloudFront distribution, with the caching and the redirects and the security headers all defined as configuration instead of clicked into a control panel. The agent did the bulk of the wiring. I did the part you cannot delegate, which was deciding how it should fail.

That phrase matters more than it sounds. The move taught me as much as it migrated. Doing it well meant naming the failure modes in advance and rehearsing them, instead of discovering them in production. What happens when a deploy is incomplete. What happens when a cache header is wrong. What happens when a path that worked on the old host does not resolve the same way on the new one. The platform itself kept nudging me toward the same habit: assume the part will fail, and build so that when it does, you already know what happens next.

## The day a deploy script deleted production

Here is the part I want to keep in, because it is the real lesson and not the marketing one.

An agent wrote a deploy script. It was good. It built the site, synced the files to S3, and cleaned up anything stale so the bucket matched the build exactly. That last behavior, deleting whatever was not in the new build, is correct right up until the build comes up short. One day a build failed partway through, produced an incomplete set of files, and the script did exactly what it was told: it made the live site match the incomplete build, which meant deleting most of the images from production.

Nothing about that was the agent being dumb. The script was logical. The bug was that a destructive operation was coupled to an assumption that the build was always complete, and nobody, human or machine, had questioned that assumption until it failed.

The recovery is the point. The images were never really lost, because the source of truth was the repository on my machine, not the bucket. I pushed them back up with a sync that only adds and never deletes, cleared the cache, and the site was whole again in a few minutes. Then I did the thing the incident was actually asking for: I changed the deploy so a bad build can no longer reach a destructive step, and so asset uploads only ever add. The failure became a permanent improvement to the system, which is the only good thing a failure is for.

I caught it, fixed it, and hardened it, and the agent did most of the typing for all three. That is the loop working as intended. Trust it to do the work. Do not trust it to be right. Keep a source of truth it cannot touch, and keep the irreversible operations behind a gate.

## It is still changing

The site is not finished, and I do not want it to be. It is a place I keep rebuilding in the open, because the tools keep getting better and because the practice of working this way is itself the thing I am trying to learn. What used to be a month of evenings is now an afternoon, and the bottleneck has moved entirely to taste and intent and verification, which is exactly where I want it.

If you want the method underneath this, I wrote it down: [an AI agent workflow that actually holds up](/2026/06/02/ai-agent-workflow-for-software-engineers/), and the longer version in [AgentSpek](/books/agentspek/), free to start reading here. And if you want the philosophy underneath the method, it is all one idea: [making a complex system legible enough to live inside](/coherent-complexity/), whether the system is a cloud platform, a codebase, or a life.]]></content:encoded>
      <pubDate>Wed, 03 Jun 2026 17:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/03/rebuilt-my-site-in-agent-mode/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/rebuilt-my-site-in-agent-mode.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>What Is Autonomous Mode? And When to Actually Trust It</title>
      <link>https://joshuaayson.com/2026/06/02/what-is-autonomous-mode/</link>
      <description>Autonomous mode is when the agent runs the whole loop without you in it: plan, act, check, repeat, until the task is done or it gets stuck. Here is what that means, how it differs from agent mode, and where the real risk lives.</description>
      <content:encoded><![CDATA[If [agent mode](/2026/06/02/what-is-agent-mode/) is you directing an AI through a task one step at a time, **autonomous mode is letting it run the whole loop without you in each step.** You give it a goal. It plans, acts, checks its own work, and repeats, until the task is done or it hits something it cannot get past. You come back to a result, not a series of approvals.

That is the promise. It is also where the term gets oversold, so let me be precise about what it actually is and where it actually works.

## The difference from agent mode is the leash

In agent mode you are in the loop. The agent makes a change, you review the diff, you send it again. There is a human checkpoint between each step.

In autonomous mode you move the checkpoint to the end. The agent runs many steps on its own: write the code, run the tests, read the failure, fix it, run again, and only surfaces when it finishes or gets stuck. The leash is longer. Sometimes there is no leash between start and finish at all.

The capability is the same underneath. What changes is how much you let it do before you look.

## Where it genuinely works

Autonomous mode shines on tasks that are **well-specified and cheaply verifiable**, where the agent can tell on its own whether it is making progress.

- Running a test suite to green: write, run, read the failure, fix, repeat. The tests are the judge.
- Mechanical migrations across many files where success is checkable.
- Long, boring loops you would never want to babysit: dependency bumps with a passing build as the gate, large-scale renames, format conversions.

The common thread is a tight, automatic feedback signal. When the agent has a reliable way to know "am I right yet," it can run the loop without you. When it does not, it wanders.

## Where the risk lives

The danger is not that the agent does nothing. It is that it does a lot, confidently, in the wrong direction, because nothing stopped it.

Two failure modes to respect. First, **a bad signal:** if the test it is optimizing toward is weak, it will happily satisfy the weak test and produce something wrong. Second, **blast radius:** an autonomous loop with the power to touch production, delete data, or push changes is a different risk class than one confined to a branch. The fix is not to avoid autonomy; it is to give autonomy a sandbox and a real verification signal, and to keep the irreversible actions behind a human.

## How to use it without getting burned

Start narrow. Let it run autonomously on things you can throw away or easily revert: a branch, a scratch environment, a test loop. Watch what it does over a few runs before you widen the leash. Keep the destructive, irreversible operations gated behind you no matter how good it gets. Autonomy is a dial, not a switch, and the skill is knowing how far to turn it for a given task. I drew the full contrast with hands-on agent mode, including how work quietly crosses from one to the other, in [Agent Mode vs Autonomous Mode](/2026/06/12/agent-mode-vs-autonomous-mode/).

I go deeper on all three modes, conversational, agent, and autonomous, in [AgentSpek](/books/agentspek/), free to start reading here. And if you want the everyday version, [an AI agent workflow that holds up](/2026/06/02/ai-agent-workflow-for-software-engineers/).]]></content:encoded>
      <pubDate>Tue, 02 Jun 2026 17:30:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/02/what-is-autonomous-mode/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/what-is-autonomous-mode.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>An AI Agent Workflow for Software Engineers That Actually Holds Up</title>
      <link>https://joshuaayson.com/2026/06/02/ai-agent-workflow-for-software-engineers/</link>
      <description>A practical, repeatable workflow for building software with an AI agent: specify, delegate, verify, record. The loop I actually run every day, with the parts that keep it from turning into slop.</description>
      <content:encoded><![CDATA[A lot of advice about working with AI agents stops at "just ask it to build the thing." That works for a demo and falls apart on a real codebase. Here is the workflow I actually run, day in and day out, on production systems.

It has four moves: **specify, delegate, verify, record.** None of them is glamorous. Together they are what separates agentic development from generating slop.

## 1. Specify before you delegate

The agent is only as good as the intent you hand it. Vague in, vague out. So the first move is not typing a prompt, it is getting clear on what you want.

For anything beyond a trivial change, I write the intent down: the outcome, the constraints, the parts that are non-negotiable. In a repo I keep a `CLAUDE.md` that tells the agent how this project works, what conventions to follow, and what not to touch. That file does more for output quality than any clever prompt, because it makes my standing intent permanent instead of repeating it every session.

## 2. Delegate the whole task, not the keystrokes

Once the intent is clear, hand the agent the *task*, not a line. "Add rate limiting to the payments endpoint and update the tests" is a task. Let it read the codebase, make the change across files, and run the suite. Resist the urge to micromanage the implementation. You set the destination; it drives.

This is where the speed comes from. The cost of writing the code drops to near zero. Your attention moves up a level.

## 3. Verify like you do not trust it

This is the step people skip, and it is the one that matters most. **AI-generated code can pass every test and still be wrong.** So verification is not a formality.

I read the diff. I run the tests. For infrastructure, I check the actual deployed behavior, not just that the command exited zero. When I moved a site to a private S3 origin recently, the agent's change was correct except for one thing it could not have known without checking: the new origin did not serve directory index files, so every subpage would have broken. I caught it because I verified the live behavior, not the build log. Trust the agent to do the work. Do not trust it to be right.

## 4. Record what you decided

The last move is the one that compounds. When you make a real decision, write down why. I use short architecture decision records for the project and a journal for my own process. It sounds like overhead. It is the opposite: it turns each session into something the next session, and the next agent, can build on instead of relearning.

## Why the loop holds

Specify, delegate, verify, record. The first and third steps are where your judgment lives, and they are exactly the steps an agent cannot do for you. That is the point. The workflow does not replace your engineering; it moves it to where it is worth the most, deciding what to build and confirming it is right, and hands the typing to the machine.

If you want the full version of this, I wrote [AgentSpek](/books/agentspek/), a book on building this way, free to start reading here. See also [what agent mode actually is](/2026/06/02/what-is-agent-mode/) and [AI-Assisted Development](/ai-development/) for how I apply it day to day.]]></content:encoded>
      <pubDate>Tue, 02 Jun 2026 17:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/02/ai-agent-workflow-for-software-engineers/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/ai-agent-workflow-for-software-engineers.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>Making Complexity Visible: You Cannot Simplify the Ocean, Only Chart It</title>
      <link>https://joshuaayson.com/2026/06/02/making-complexity-visible/</link>
      <description>When a system gets too big to hold, almost everyone reaches for the same move: make it simpler. It is the wrong move. You cannot simplify the ocean. You can only chart it. This is about the difference between simplicity and legibility, why decisions quietly migrate to whoever holds the context, and how to make a complex system visible enough to navigate without pretending it is small.</description>
      <content:encoded><![CDATA[Here is the first move almost everyone makes when a system grows too big to hold. They try to make it simpler. Flatten it, hide it, wrap it, abstract it until it fits inside one tired head at the end of a long day.

I made that move for years. It is the wrong one, and understanding why it is wrong is the most useful thing I have learned about building anything large.

And when simplifying does not work, the next reflex is to buy a tool. Another dashboard, another tracker, one more pane of glass to watch. It feels like progress because it is motion. It rarely helps, because the information you needed was already there, scattered across a dozen places and never assembled into one view. So let me say the thing plainly, because it took me too long to see it. We do not have a tooling problem. We have a legibility problem.

You cannot simplify the ocean. You can only chart it.

## Two Kinds of Complexity

Some complexity is junk. Fred Brooks called it accidental complexity back in 1986: the mess we make ourselves, the tangle that exists only because nobody cleaned it up. Dead code. A config that needs three files to say one thing. A process with a step that made sense in 2019 and survives out of pure habit. Cut all of that. Cut it without mercy. The world is better with less of it and you will never miss it.

But under the junk there is another kind, and Brooks named that one too. Essential complexity. The complexity that lives in the problem itself. A payment system is genuinely hard because money is genuinely hard. A distributed system is genuinely hard because the network genuinely lies to you. A family is genuinely complicated because people are. You cannot refactor that away. It is not a mess. It is the thing.

The mistake is treating the essential kind like the accidental kind. You keep reaching for the delete key on something that will not delete, and every time you fail you feel a little more like the problem is you. It is not you. You are trying to drain the sea with a cup.

The ocean does not get smaller because you wish it. It does not owe you a pond. So the real question stops being *how do I make this small enough to hold* and becomes something better: *how do I learn to see it whole without pretending it is small.*

That is legibility. And it is a different craft than simplicity entirely.

## A Chart Is Not a Smaller Ocean

A nautical chart does not shrink the sea. The water is exactly as deep, the rocks exactly as sharp, the storms exactly as indifferent as they were before anyone drew a line. What the chart changes is you. It lets one human being stand on a deck and hold a piece of the ocean in their mind, enough of it to make the next good decision, and the one after that.

Korzybski said the map is not the territory, and people usually quote him to warn you off the map. I read it the other way. Of course the map is not the territory. That is the whole point of the map. The territory is too much. The map is the part of the territory a human can carry.

Legibility is when a system shows you its own state before you have to go hunting for it. Not when you *can* answer a question about it if you know the question and where to dig. When you can glance and know. The distance between those two is the distance between querying the sea and reading it.

James Scott used the word legibility as a warning. He showed how states flatten messy living things into grids and ledgers so they can tax and control them, and how much gets destroyed in the flattening. He was right, and the danger is real, and it is the exact danger I am not talking about. The flattening he feared makes the territory legible to a distant ruler by killing whatever does not fit the grid. I mean the opposite motion. Legibility for the navigator, not the king. A chart you make so you can move through the thing wisely, not a grid you impose so you can pretend it is simpler than it is. The first keeps the danger on the page. The second paints over it.

## Where the Decisions Go

Here is what illegibility actually costs, and it is far more than slow work.

When a system is hard to see, decisions quietly migrate to whoever happens to hold the context. Not the right person. The legible-to person. The one who set it up, who remembers, who has the whole tangle loaded in their head because they have been carrying it for two years.

You have met this person on every team. They are the only one who really understands the deploy. The only one who knows why the numbers in that report never quite match. The only one who can say whether the system is actually healthy or just looks healthy from the outside. They are not hoarding anything. They simply *became* the map because no other map exists, and now the system cannot think without them. They cannot take a real vacation. The team's intelligence is bottlenecked on one person's memory and one person's availability.

Multiply that across a company and you get an organization whose real intelligence is far smaller than the sum of its people, because most of what it knows is trapped in a handful of heads, illegible to everyone else. The same thing happens to a household where one person holds the whole budget in their gut, or a project where the true status lives only in a lead's quiet anxiety. The state is real. It is just not visible. So the circle of people who can think well about it stays small, and stays tired.

Make the system legible and you widen that circle. That is the entire payoff. Not a prettier screen. A larger number of people who can hold the whole and reason about it. Coordination, stripped down to the bone, is mostly a group of people managing to look at the same picture at the same time.

## Giving the System a Face

So what do you actually build. You give the system a face.

I have spent a lot of years building these surfaces. Live views of systems that used to answer only to the person who built them. Maps of processes that used to live in somebody's head. Dashboards, when the word does not embarrass me, though the word undersells the thing. The idea underneath all of them is the same, and it is almost too simple to say out loud: stop making people query for state, and let the state be ambient.

Ambient is the key word. You want the state of the system to register the way it registers when a room goes quiet. Before you have consciously checked anything, before you have run a single query, you already feel that something is off. A good live view of a running system does that. You walk past it and your body knows the shape of the day. The knowledge stops being something you go and fetch and becomes something you simply have, the way you have the weather.

And the thing that changes when you build it well is never mostly technical. It is that people who do not own the system can suddenly tell when it is wrong. Conversations get shorter, because nobody has to reconstruct the picture before the real discussion can start. The thing becomes a shared object, and a shared object is half of what coordination even is. You did not make the system simpler. You made it legible, and legibility did the rest.

## Coherence Is Not Simplicity

This is the turn the whole essay has been walking toward, so let me say it plainly.

The goal is not a simple system. The goal is a coherent one.

Simplicity throws information away. Coherence keeps the information and arranges it so a human can hold it. A simple map of the ocean is a blue rectangle, and it will get you killed. A coherent chart has every rock and current and depth still on it, all the danger intact, organized so that a person on a moving deck can read it in the dark and live. Simplicity lies to make you comfortable. Coherence tells the truth in a shape you can use.

I have started calling the thing I am chasing *coherent complexity*. The state where a system stays as complex as it truly is, and stays understandable enough to navigate anyway. You do not pretend the sea is a pond. You become a navigator. That is the only relationship with anything genuinely hard that does not involve pretending, and once you have the phrase for it you start seeing it everywhere, or seeing its absence.

There is even a law for why simplicity fails here. Ashby, in early cybernetics, called it requisite variety: to control a system, your model of it has to be at least as rich as the system itself. Shrink your model below the complexity of the thing and you lose your grip on it. You cannot out-simple a complex world. You can only build a richer way of seeing it. The chart has to carry enough to match the sea. That is not bureaucracy. That is survival.

## The Same Move, Everywhere

Once you have the move, you cannot stop seeing it, and it stops being only an engineering trick.

A life is an illegible system. The state is real and it is smeared across your calendar, your body, your bank account, your relationships, your half-finished intentions, and almost none of it is visible at once. Most people run a life the way a tired team runs a system nobody charted: by holding it all in an anxious head and hoping. I keep my own time by the stars and the decans for exactly this reason. Not because the cosmos sends instructions, but because a slow steady cycle is a chart for a year, a way to make a long sprawling stretch of time legible enough to move through on purpose instead of drifting.

A family is an illegible system. A portfolio is an illegible system. A company is a thousand of them stacked on each other. The move is identical every time. Find the place where important state is real but invisible, and give it a single surface where a human can hold it whole. Cluster, release, codebase, quarter, marriage, life. Different oceans. The same craft of the chart.

## The Navigator's Art

So here is where I have ended up, after years of reaching for the delete key on things that refused to delete.

You do not conquer a complex system. You do not shrink it down to where it stops being itself. You learn to read it. You build the chart that lets a human stand in front of the whole moving thing and know, in seconds, where they are and what to do next. And then you hand the chart to the next person, and the next, until the knowledge that used to live in one exhausted head lives out in the open where anyone can use it.

The sea never gets smaller. That was never the deal. The deal is that you can become someone who reads it. A navigator is not braver than a drowning person. They can just see. That seeing is the whole of the freedom, and it is buildable, and building it is some of the best work there is.

That is what I mean by making complexity visible. Not making it simple. Making it legible enough to love.

Dip the oar. The other end rises. Reach for the next dip. Let's go.

---

## Related reading

- [Complexence](/complexence/): the human capability this whole craft exists to build, the person who can read the chart under load and still move
- [DevOps Beyond Automation: What Compounds in a 15-Year Engineering Career](/2026/05/27/devops-beyond-automation/): the deeper goal under every tool I build: systems that change without breaking
- [Living with Antifragility: How I Build Systems and a Life That Gain from Disorder](/2026/05/30/living-with-antifragility/): why you keep the danger on the page instead of painting over it
- [AWS Is Math, Kubernetes Is Physics](/2026/05/31/aws-is-math-kubernetes-is-physics/): the grand and the granular, held in one view
- [What Is People of the Stars?](/2026/05/26/what-is-people-of-the-stars/): keeping time by the stars as a chart for a year

*Sources for the ideas borrowed here: Fred Brooks on essential versus accidental complexity (No Silver Bullet, 1986); Alfred Korzybski on the map and the territory (Science and Sanity, 1933); James C. Scott on legibility and the state (Seeing Like a State, 1998); W. Ross Ashby on requisite variety (An Introduction to Cybernetics, 1956).*]]></content:encoded>
      <pubDate>Tue, 02 Jun 2026 17:00:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/02/making-complexity-visible/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/making-complexity-visible.webp" type="image/jpeg"/>
    </item>
    <item>
      <title>Claude vs Copilot for DevOps: A Practitioner&apos;s Comparison</title>
      <link>https://joshuaayson.com/2026/06/02/claude-vs-copilot-for-devops/</link>
      <description>I use GitHub Copilot at work and the Claude Code CLI at home, every day. Here is the firsthand comparison for DevOps and infrastructure work, from someone who ships with both, in the context each one actually lives in.</description>
      <content:encoded><![CDATA[I use both of these every day, in two different lives. At work I use GitHub Copilot in VS Code, exclusively, because Claude Code is not available to me there. At home, where I pick my own tools, I run the Claude Code CLI for almost everything and keep VS Code open beside it as my reviewer, my diff viewer, and my editor. So this is not a migration story told from the far side. It is a daily, side-by-side comparison, written for DevOps and infrastructure work specifically, by someone who ships real work with each tool in the context that tool actually lives in.

The short version: for line-by-line completion they are close, and for **agent mode**, the kind of work where you direct a model to change many files and verify itself, Claude Code is the stronger tool when the choice is mine. Here is why, with the parts that actually matter for infrastructure work.

## They are aiming at different jobs

GitHub Copilot started as an autocomplete and grew outward. Its center of gravity is still the editor: you are typing, it is suggesting. That is genuinely useful, and inside VS Code it is well integrated.

Claude Code starts from the other end. It is a terminal-native agent built to take a task, read the repository, make the change across files, run the commands, and report back. The editor is not the center; the task is.

For DevOps work that distinction is the whole game, because infrastructure changes are rarely one line in one file. A rate limit, a new origin, a CDK change, a CI pipeline edit, each of those touches several files and a test or a deploy. The tool that holds the *task* beats the tool that holds the *line*.

## Where each one wins

**Copilot wins** when you are heads-down writing code in the editor and want fast, low-friction completion. It is also the path of least resistance if your whole team already lives in VS Code and you want one consistent surface.

**Claude Code wins** when the unit of work is bigger than a function: a multi-file refactor, standing up infrastructure, wiring CI, migrating config across a repo. It reads the codebase as context, makes coordinated changes, and runs the verification step itself. For the way I work, that is most of the day.

## A concrete DevOps example

I recently moved a static site's CloudFront distribution to a private S3 origin behind an Origin Access Control, with a basic-auth gate at the edge. In Claude Code I described the end state. It changed the origin, wrote the bucket policy, attached the function, and flagged the gotcha that bites everyone on this setup: the S3 REST endpoint does not auto-serve directory index files the way the website endpoint does, so subpaths break unless you rewrite them. That is the kind of cross-file, knows-the-trap work where the agent earns its place.

Copilot would have helped me type each of those files faster. Claude Code did the task and showed me the diff.

## A harder one: the deploy that half-shipped

For a while my deploy had a bug I could feel but could not name. Some days I would ship a new post, watch the script run green, and then find the page returning a 404 in production while the new hero image sat in the bucket like nothing was wrong. A second manual run always fixed it. I had been filing it under flakiness and moving on.

The actual cause was ordering. The script synced the entire asset tree first, close to two gigabytes including a dead WordPress backup folder I had forgotten was even there, and only after that did it ship the HTML and invalidate the CDN cache. When the big asset sync timed out on those legacy files, the script exited, and because it exited on the asset step it never reached the two steps that actually matter: the HTML sync and the cache invalidation. The new images uploaded. The new page never did.

I handed Claude Code the whole script and the symptom. It read the thing end to end, named the ordering as the bug, and rewrote the deploy so the critical path runs first and cannot be aborted by a slow upload, and so it ships only the handful of files that actually changed instead of re-scanning two gigabytes to move three. That is the part autocomplete cannot reach. The fix was not a cleverer line. It was seeing that a step near the bottom of a hundred-line script was starving the two steps the whole deploy existed to run. You have to hold the entire file, and the shape of how it fails, to catch that.

## The difference that decides it: context

Underneath all of this is one thing, which is how much each tool knows when it acts. Copilot's context is built around your cursor. It sees the file you are in and some of what is near it, and it is very good at guessing the next few lines from that. Claude Code's context is the repository. Before it changes anything it can read the files that matter, the config, the tests, the place the thing you are touching gets used three directories away.

For DevOps that is the difference between a tool that helps you write a Terraform block and a tool that notices the block you are writing contradicts a variable defined in another module. The first saves keystrokes. The second saves an afternoon.

The other half of it is the loop. Copilot suggests and you run it. Claude Code makes the change and then runs the test or the plan itself, reads the output, and fixes what broke before it hands the work back. On infrastructure, where the feedback is a plan diff or a failed apply rather than a red underline in the editor, having the tool close that loop itself is most of the value.

## When Copilot is the right call

I reach for Claude Code whenever the choice is mine, but there is a real case for Copilot and I do not want to flatten it.

If your day is spent inside one service writing functions, completion at the cursor is faster and quieter than describing a task to an agent. There is no context to set up and nothing to review across files. You type, it suggests, you keep moving, and the latency is lower because the job is smaller.

The pricing matters too. Copilot is a flat monthly seat. Claude Code bills for what the agent actually does, and a heavy agent-mode day is real money. If your work is mostly in-editor and your budget is fixed, the flat seat is a sound choice, not a compromise.

And sometimes the tool is simply not yours to pick. At work I use Copilot because it is what I am given, and that is the position a lot of engineers are in. If that is you, the good news is that Copilot in an editor you know is a genuinely strong place to work from, and nobody should feel behind for using it.

## The caveat that cost me the most

Agent mode fails differently than autocomplete, and this is the one I had to learn the hard way. When Copilot is wrong it is wrong in one line, and you catch it as you type. When an agent is wrong it is wrong across several files with great confidence, and the work looks finished. The review burden moves up the stack, from watching a line to reading a diff you did not write. That is a discipline you have to build, not a thing the tool hands you. It is also most of why I keep VS Code open next to the CLI at home, and why I wrote up [the code-review workflow I actually run on agent-written diffs](/2026/06/11/ai-code-review-workflow/). It does not change which tool I choose when I am free to choose. It changes how I work once I have.

## What I actually use

Both, every day, and not entirely by choice on one side. At work Copilot is what I have, and for in-editor completion it carries the day fine. At home, where nothing stops me from reaching for either, I run the Claude Code CLI for almost everything bigger than a single edit and use VS Code to read the diffs it hands back. If you do DevOps and your work is mostly multi-file changes and infrastructure, and the tool is yours to pick, that is the one I would start with. If you live inside a single service writing functions, or your employer picks for you, Copilot's editor integration is a real comfort.

There is more for me to learn in each of these than I have learned so far. Copilot has depth in the editor I have not worked all the way through, and Claude Code keeps showing me ways to scope a task I would not have tried a month ago. This is a photograph of how I work now, not a finished verdict on either tool.

If you want the longer argument for working this way, I wrote a book on it: [AgentSpek](/books/agentspek/), free to start reading here. For how it feels in practice, [AI-Assisted Development Is Not Vibe Coding](/2026/05/07/ai-assisted-development-is-not-vibe-coding/), and for [what agent mode actually is](/2026/06/02/what-is-agent-mode/) if the term is still fuzzy.]]></content:encoded>
      <pubDate>Tue, 02 Jun 2026 16:30:00 GMT</pubDate>
      <guid isPermaLink="true">https://joshuaayson.com/2026/06/02/claude-vs-copilot-for-devops/</guid>
      <category>essays</category>
      <dc:creator>Joshua Ayson</dc:creator>
      <media:content url="https://joshuaayson.com/images/essays/2026/06/claude-vs-copilot-for-devops.webp" type="image/jpeg"/>
    </item>
  </channel>
</rss>