Software Factories
by John Robinson @johnrobinsn
New capability, old constraint #
Something foundational shifted under software development. LLMs that specify, code, review, test, deploy. Agents that can run those capabilities in parallel, in the background, on real work.
What that changes about capacity is enormous. What it doesn't change is the constraint that mattered all along: your attention is the scarcest input in the system.
The new tools don't relax that constraint. They sharpen it. Because now the central design question is how to deploy these capabilities against real software work in a way that respects the scarcity of your attention, minimizes missed expectations, and keeps what ships good enough to live with over time.
That's a design problem. It has structure. It has axes. And most of the current tooling in the agent-coding space is only getting one of them right.
The scarcity isn't code #
Human attention is the ultimate scarcity in software work. Not skill. Not tools. Not compute. Attention — the finite hours per day of focused, considered engagement that a skilled practitioner has to give.
Every step in traditional software production is bounded by attention. Someone has to read the requirements. Someone has to design the module. Someone has to review the PR. Someone has to sign off on the deploy. The critical path runs through humans, one attention-transaction at a time.
Earlier attempts to industrialize software production — templates, DSLs, code generators, whole methodologies borrowed from manufacturing — tried to automate the making. Code that stamps out more code. Some of it stuck; most of it delivered less than promised. The reason is instructive: making wasn't the constraint. Programmers already generate code quickly. What was slow was everything around the code — deciding, checking, reconciling — and that never got automated because it required judgment.
Agent-based orchestration inverts this. Agents can make. They can also review, revise, test, package, and file a PR. They can even make a first-pass judgment about whether the result matches the intent — and they must, because deciding what to surface is a judgment. What they can't do is originate the intent, or hold final authority over whether the outcome is acceptable. Those two touchpoints — saying what you want, and signing off on what you got — are where human attention still belongs.
Everything else can move to the agents. The industrialization move, done right, is to squeeze the human attention footprint down to the moments that actually require judgment, taste, or style — and let the agents handle the rest.
One caveat before going further, because the rest of this post leans hard on minimizing attention. Not all attention spent on software is cost. Some of it is investment: reading a diff you didn't strictly need to read is how you keep a working model of the codebase, notice drift, and stay able to make the judgment calls the agents are routing to you. An orchestrator that treats every unit of attention as waste will eventually produce a human who can't evaluate the summaries they're handed. The goal is not zero attention. It's attention spent where it compounds.
Which is exactly what a well-designed orchestrator does.
The three axes of orchestrator design #
Every human-agent interaction is optimized — or fails to be optimized — along three distinct axes.
Bandwidth-when-attending is the first. Given that you are engaged with the system, how much information can you exchange per unit time? Menu clicks and dialog forms are low-bandwidth. Natural language is higher. Voice is often the fastest way to express abstract intent — language is already the abstract layer — though it's weak for anything that needs precision, which is exactly why the system has to pick modality per moment. Screen sharing is highest-bandwidth for handing over desktop state. Camera for physical world state. The orchestrator picks the right modality for the moment — and, just as important, adapts content between them. Coding agents naturally emit long text streams; the orchestrator uses another agent to condense that into voice-suitable dialog, a structured summary, or a widget on the nearest screen. The intelligence isn't just picking a channel; it's translating continuously.
I wrote about this on the consumer side last week. The bandwidth axis is why voice-first works when it works, and why multimodal has to be more than a bullet point on a marketing site.
Attention-required is the second axis. Given a desired outcome, how many units of your attention are needed to get there? Traditional apps require constant presence — you sit at the keyboard, you watch the output stream, you approve each step. The orchestrator instead dispatches to specialist agents that run in the background. You're absent until the outcome lands. Only when the system genuinely needs your judgment do you re-engage.
Exchange choreography is the third — and the most under-discussed. When exchanges with you do happen, how are they structured? Streaming raw agent output message-by-message is choreography-broken. Batching related decisions, aggregating results into standardized summary formats, prioritizing which interrupts fire immediately vs. which queue for a scheduled review — that's choreography done well. The orchestrator's job is not just to dispatch. It's to choreograph the information back to you in a shape that respects your attention.
Put them together:
| Axis | What it optimizes | Common default | Well-designed orchestrator |
|---|---|---|---|
| Bandwidth-when-attending | Efficiency per unit of engagement | Menu clicks; dialog forms | Voice for abstract intent; multimodal per context |
| Attention-required | Frequency of engagement per outcome | Watching every step; approving every action | Dispatch; run in background; interrupt only when needed |
| Exchange choreography | Structure/sequencing/batching of exchanges | Streaming raw output; unbatched interruptions | Batched decisions; aggregated summaries; prioritized interrupts |
Put more simply: the cost to you is how often you have to engage, times how much work each engagement demands. The three axes attack different parts of that product. Attention-required lowers the frequency. Choreography lowers the structural work per engagement. Bandwidth lowers the friction inside each one. Optimize any two and ignore the third and you leave value on the table — a background agent that dumps fifteen raw logs on you has solved attention and bandwidth and failed choreography.
One thread runs through all three: the orchestrator's core job is translation. Between modalities on the bandwidth axis. Between raw output and choreographed exchanges on the choreography axis. Between what the system produces and what your attention can efficiently receive, everywhere. Not passthrough. Not dispatch. Translation — continuous, contextual, per-moment.
The framework is dynamic, not static #
None of these axes are settings you configure once. Every one of them is context-sensitive. The optimal reading shifts with the moment.
On the bandwidth axis, the rule isn't "always use the highest-bandwidth channel." It's "use the highest-bandwidth channel appropriate to the circumstances." Voice is silent in a meeting. Screen sharing is unusable in the car. Camera is impolite in company.
The other two axes work the same way. On the choreography axis: developer in deep work → batch more aggressively, interrupt less. Developer available at their desk → interrupt normally. Developer away or driving → surface only critical items via voice. Developer in a meeting → suppress non-critical entirely. On the attention axis: weekend batch is fine for routine work; middle of an outage demands real-time engagement. The system reads whether attention is available or scarce right now, and adapts.
Reading that context is itself a judgment the system will sometimes get wrong — interrupting the deep-work block, or sitting on something that should have fired. A wrong guess about whether attention is available right now is a choreography failure of its own, and the system needs to learn from those the same way it learns your preferences.
Get one axis right while ignoring circumstance and you've built a rigid tool. The intelligence is in reading which axis matters most in the moment.
What good choreography looks like #
The concrete producer-side examples land better than the abstract framing.
Weekly status report, one exchange: "Here's what shipped this week, here's what stalled, here are three decisions I need from you." Structured summary format. Standardized shape. You review 20 things in the time it used to take to review one, because the shape is predictable and the surfacing is discriminating.
Architectural interrupt vs. cleanup batch: design decisions get real-time surface — those need judgment. Style, lint, routine refactor: batched into weekly review. Same underlying flow of work; radically different attention footprint.
Aggregated agent output: fifteen sub-agent runs collapse into one coherent status report, not fifteen raw streams for you to context-switch through.
Just-in-time surfacing: don't tell me until it's actionable. Six status updates that could have been zero were probably choreography failures, not information transfers.
Learned preferences: the orchestrator observes how you actually work — that you prefer summaries over detail, that you hate approve-per-file, that your focus hours are 8-11 AM — and adjusts. Your future exchanges get lighter without you having to configure a thing.
Notice what's missing from every one of these: the interactive drip of "the agent did this, then it did that, then it wants to know if..." That's not the shape a well-designed factory takes. That's the shape today's coding agents take — which is a different problem.
The quiet-failure problem #
Everything above assumes something I haven't defended: that when the orchestrator reports "five items shipped clean," five items actually shipped clean.
That assumption is the whole game. The reason developers today sit and watch the stream is not that they enjoy it. It's that unsupervised agents still produce plausible-looking work that is subtly wrong — a test that asserts the wrong thing, a refactor that quietly changes semantics, a "fix" that suppresses the symptom. Watching is a crude verification strategy, but it is a verification strategy. Take it away without replacing it and you haven't reduced attention; you've deferred it to the incident.
So a well-designed orchestrator has to own verification as a first-class concern, not treat it as the coding agent's problem. Concretely:
Evidence, not assertions. A summary that says "tests pass" is a claim. A summary that says "tests pass, coverage of the changed lines is 94%, here's the one branch that isn't covered" is evidence. The choreography layer should compress evidence, not replace it with confidence.
Surfaced uncertainty. Agents know, imperfectly, when they're unsure — when a spec was ambiguous, when they made an assumption, when a change touched something they didn't fully understand. That uncertainty should flow to you as a first-class signal. An orchestrator that hides it to keep the report tidy is optimizing choreography at the expense of correctness.
Trust that's earned per task type. Absence is safe for a lint pass long before it's safe for a schema migration. The right default isn't "run everything in the background"; it's "run in the background where the track record supports it, and widen that set as the record grows." Trust calibration is part of the orchestrator's job, and it should be legible — you should be able to see why the system decided you didn't need to look.
A path back to the raw stream. Summaries are the default, not the ceiling. When something feels off, the full trace should be one click away. Compression that can't be uncompressed isn't choreography; it's concealment.
None of this contradicts the three-axis framework. It's the precondition for it. The attention axis only pays out if the quality bar holds while you're absent, and the choreography axis only pays out if what gets batched and summarized is true.
Why current agent tools fall short #
Claude Code, Cursor, Devin, Copilot, opencode — all real, all useful, and all built around the same interaction model.
To be fair about what they can do: most of them can run headless, in CI, or as background tasks. Most have permission modes that stop the approval dialogs. The raw ingredients for absence exist. So the critique isn't "these tools can't run without you." It's that when they do, nothing sits between their output and your attention. You get the same stream, just later. The choreography layer — batching, aggregating, prioritizing, translating across modalities, deciding what deserves an interrupt and what waits for Friday — isn't a feature of any of them. It's not their job. They're execution engines.
And their default mode, the one nearly everyone actually uses, is the interactive one: you sit at the keyboard, you watch each step stream by, you approve, you context-switch across sessions. That default is bandwidth-maximized — natural language in, natural language out, the highest-bandwidth interface most developers have ever had. It's also attention-maximizing and choreography-absent.
They feel powerful and they feel exhausting, and both experiences trace to the same root: they're bandwidth-maximized point tools, not orchestrators. You're drinking from a firehose of well-articulated interruptions.
That's not the endpoint. That's the interregnum — a stage where bandwidth got much better but choreography and attention are still stuck in the previous era's assumptions. The endpoint is autonomous execution with orchestrated choreography of the exchanges that do require you, sitting on top of verification you can inspect. Not fewer capabilities; different shape.
What it looks like when it works #
You describe a feature by voice from the car. By the time you're home, the PR is filed, the tests pass, a preview environment is up. You click through it on the TV while making dinner. You have one design question; the orchestrator responds. You approve; the PR merges.
You dictate a batch of small work items before dinner. The next morning: a single consolidated report — five items shipped clean, two need your review, one hit an ambiguity worth talking about. Fifteen minutes to triage the whole batch.
And when one of the "shipped clean" items wasn't — because eventually one won't be — the report is honest about what was verified and what was assumed, the full trace is a click away, and the orchestrator's confidence in that class of task goes down until it earns it back. The system's model of your trust is as important as its model of your attention.
You're in the middle of a real outage. The orchestrator knows. Interrupts get priority; batches get suspended; every exchange is optimized for velocity over politeness. Two hours later, incident resolved; the orchestrator files the post-mortem draft for your morning review.
None of that requires you to be at the keyboard. None of it requires you to be watching output stream. None of it requires you to context-switch through fifteen raw agent voices. What it requires is an orchestrator that treats your attention as the scarcest input in the system.
Now, for the first time, we can actually build it.
Coming next #
The three-axis framework is the what and the why. The open question is architectural: where does the orchestration layer live, and why can't it just be another feature of the coding agent you already use?
The short version: the coding agent is the wrong place for it, because the coding agent's context is a single task and the orchestrator's context is you — your calendar, your focus hours, your trust history, the fifteen other things in flight. That's a different kind of state, held over a different time horizon, and it wants to sit above any particular tool rather than inside one.
Next post works through that pattern — a personal meta-layer above the coding agent — and why that separation matters more than any single-tool improvement.
Get updates like this. Occasional, low-cadence, real-news-only.
Follow along at storminthecastle.com — or reply if you're building in this space.
Share on Twitter | Discuss on Twitter
John Robinson © 2022-2026
- Previous: AI will be your only UI