The Assembly Line Nobody Reads
Hohen Ventures10 min read
Software development is becoming a production process, and the question that decides whether that helps you is where you keep the lights on. You can build a system where agents write, test, and ship code while a person reads what matters before it goes out. Or you can build one where the code ships and no human ever looks. Both feel like progress. Only one of them stays cheap after the first quarter.
The idea is not new. Bob Bemer described it in 1968 in a paper called "The Economics of Program Production," where he imagined software rolling off a line the way car parts do. For half a century the dream mostly failed, because ideas resist stamping in a way that sheet metal does not. The last two years changed the inputs enough to make the dream worth reexamining. What follows leans heavily on Dex Horthy's talk at AI Engineer World's Fair, "Harness Engineering is Not Enough: Why Software Factories Fail," extended with what breaks when you actually run these systems.
Start with the part everyone gets wrong: the constraint.
The Constraint Was Never Speed
You can only give a loop as much autonomy as you can verify cheaply and reliably, and no more than that. Generation is not the bottleneck. Verification is.
Think of the pipeline as a funnel. The mouth is generation, and it is wide. More agents, faster models, higher parallelism all widen it further, and all of it costs almost nothing. The neck is verification, and it does not widen. Human attention is finite and does not scale with compute. So when you pour more generation into a fixed neck, you do not get more shipped work. You get a deeper pile of unreviewed pull requests waiting at the gate.
This is the rule worth naming and keeping: back pressure. Autonomy cannot exceed verification. Every argument about how fast a software factory can safely run reduces to this one line.
A tempting response is to wait for better models to close the gap. That response misreads the problem. Training a model to pass unit tests is straightforward, because the reward is instant and legible. Training a model to produce code that stays maintainable for a decade is not, because the signal that tells you whether an architectural decision was good arrives in months and years, not seconds. Clean gradients over that timescale are impossible to compute. So the models improving fastest are improving at the thing that is easy to measure, not the thing that is expensive to get wrong. Better generation and better verification are separate problems, and treating them as one produces false confidence about how much autonomy is safe to hand over.
Three Words That Build Everything
Every agentic system, whatever the marketing calls it, is three concepts stacked on each other.
A loop is one agent doing a single job on repeat: gather context, act, check the result, repeat until a condition is met. It is the smallest unit of agentic work. The discipline of loop engineering is that you stop prompting the agent turn by turn and instead build the small system that prompts it for you.
A harness is the walls around a loop. It is the sandbox the loop runs in, the tools it can reach, the memory that survives between runs, and the gates that decide what "done" means. The loop is the behavior. The harness is the environment the behavior runs inside. Hand a raw model no harness and it will spin forever. The harness is what makes the loop useful and safe to run.
A software factory is many harnessed loops running at once, fed by a queue and drained through a review gate into production, with humans owning it from above. It is not a bigger agent. It is an org chart made of loops.
The shift this asks of you is real. You stop writing code and start building and running the machine that writes code. The unit of work moves up a level, from the individual change to the loop, the harness, and the flow between them.
The Factory as a Closed Circuit
The cleanest way to picture a software factory is a circuit that never stops turning.
Intent enters from two directions. Engineering leadership and individual engineers push work into a queue. Incidents and user requests push into the same queue as signals. The harness pulls an item, produces a change, and hands it to a bank of automated checks: CI, tests, static analysis, security scanning. Those checks run against the change at almost no cost and with no active human involvement. The change reaches the review gate. After approval, it deploys, production monitors it, and monitoring data loops back into the signals that started the cycle.
Now look at the cost of each box. Generation is nearly free. Tests are nearly free. Scanning is nearly free. Every stage runs at scale for negligible cost except one. The review gate is the only expensive box, and it stays expensive no matter how much compute you throw at the rest. That box is judgment. Every real debate about how fast and how often you can ship lives inside it.
When the Lights Go Off
A dark factory ships code that no human has read, verified only by other machines. The name comes from manufacturing, not software.
A lights-out factory runs with the electricity to the lights switched off, because the only workers on the floor are robots and robots do not need to see. FANUC has run factories like this in Japan since 2001. Xiaomi opened a heavily automated one in 2024. What they share is a product built and shipped without a single human examining any of it. The "dark" is not a mood. It is a literal description of a floor with no one reading.
In software, the floor is the diff. In a dark factory, whoever wrote the diff, whoever reviewed it, whoever shipped it, all of them are gone. What remains is a change that only the machines that built it have ever seen.
Reaching this state is easier than it should be. The review step slows everything, so removing it makes throughput appear to jump overnight. It feels like breaking through a wall. That feeling is honest, and so is the cost hiding behind it. The cost simply does not arrive on the same schedule as the speed.
The Debt You Cannot See on the Dashboard
Here is the cost, named plainly.
Comprehension debt is the widening gap between how much code exists and how much any human still understands. A dark factory does not pay this debt down. It takes it on as fast as it can, with the tests green the entire way.
Models handle localized, well-specified tasks well. Push past that, into a change that touches a large or unfamiliar part of a mature codebase, and model-only coding hits a structural wall. A weekend project reaches a workable state in a few cycles. An enterprise system a decade into its life is a different animal. It has to be maintained at a professional pace, under production constraints, against decisions made by people who left years ago. Three to six months into a fully automated workflow on that kind of system, you are already swimming in code no one has read. The agent struggles not because it lacks skill but because the environment holds more than the harness can contain.
The evidence here is direct. Dex Horthy ran a fully automated code factory for roughly four months with no human reading the output. The failure that eventually surfaced took painstaking manual debugging to locate. Underneath sat a conflict between two numbers. One is token utilization, which the industry currently treats as progress. The other is how much of the system any person still understands, which the dark factory quietly drives toward zero. It optimizes hard for the first and sacrifices the second without ever showing it on a chart.
The reckoning does not announce itself. It shows up quietly, late, and expensive.
Turning the Lights Back On, Upstream
A lit factory is the same pipeline with the lights left on where judgment lives. Agents still do most of the building. A human reads what matters before it ships, and the lights stay on wherever a wrong call is costly.
The mistake is assuming "lit" means bolting review onto the end. It does not. A lit factory moves human judgment upstream, into product, design, and architecture, before any agent starts a loop. An hour spent reviewing a two-hundred-line plan beats a day spent excavating a two-thousand-line diff to reconstruct what the plan even was. You review the decision before it is built rather than reverse-engineering it afterward.
The safety net that makes this work is unglamorous. It is a set of architectural practices the field has always endorsed and consistently underfunded:
- Strong types and method signatures, so mistakes surface at compile time instead of in production.
- Test seams, so behavior can be pinned and change can be observed.
- Legible code layout, so the next reader, human or model, knows where to look.
- Short call stacks and clear component boundaries, so a change has a small blast radius.
- Dependency injection, so one piece can be swapped without breaking the rest.
None of this is new. What is new is the second job the architecture now does. It stops being hygiene and becomes a hard-to-fake safety net against the mistakes agents will make. That net has to live outside the model, because the model will not supply it. The agents that feel most capable, Claude Code and Codex among them, are trained against their own harness and tools. They are fluent with the mechanics of writing code. They are not trained against long-term maintainability, because no reward signal measures it on a useful timescale.
So investing in deliberate architecture is how you buy back autonomy. The architecture catches what the model cannot, which lets you run some loops unattended without stacking up comprehension debt. A nightly job that fixes one lint violation, commits, and opens a small pull request is a safe lights-out loop. The scope is narrow, the diff is readable, the check is unambiguous. A loop that touches auth, billing, or a public API contract is not. Keep the lights on there.
What Earns a Loop Its Autonomy
The back-pressure rule decides every switch, whatever you call it.
A loop earns fully automated status only when its check is cheap, runs at high frequency, and cannot be easily faked. Green-or-red test results, type gates, property tests, and a review agent working against a real rubric all qualify. The check has to answer immediately and must not drift over time. When "done" can be proven by a machine rather than asserted by the agent, the loop has earned the dark.
Length is the other factor. Short loops verify more easily than long ones. An agent holds coherence through roughly three to ten steps and starts losing the thread past twenty. The cause is context accumulation: the more the agent drags along, the more likely it wanders off course. Short loops produce short diffs, and short diffs are cheap to verify. Long loops bury their mistakes in the later steps, which is another way of saying they never earned lights-out status in the first place.
Keep the lights on when a wrong answer is expensive and only a person can catch it. Subtle production bugs no test covers, changes with a large blast radius, and decisions that will shape a year of work all belong in that category. Here your attention is not overhead. It is the essential, costly part of the process, and it does not leave the software.
The failure to avoid is treating the switch as one setting for everything. All dark, and you tear the whole thing down four months later when the debt comes due. All lit, and the review gate becomes a wall that no one can clear, and throughput collapses. The skilled work is deciding, loop by loop, where each switch belongs.
Why the Flowchart Came Back
Design a loop carefully and you will find you have built a directed graph, whether or not you called it one. Every node is an explicit step. Every edge is an explicit condition.
That sounds like heavy structure, but most of it was always there. Any program can be expressed as a control-flow graph. The only genuine novelty of the pure agentic loop was throwing the diagram away and letting the model pick the path one tool call at a time until it declared itself finished. That felt like freedom, right up until it met a ten-year-old codebase with no readable map. The discipline everyone is now rediscovering, owning your control flow, is just walking that graph back around the loop. We drew programs as flowcharts for a reason. The reason held.
Picture a bug fix two ways. As a pure loop, the agent decides everything as it goes: which problem to chase, which code to change, which tests to run, whether to run tests at all, whether to try again or call it done. As a graph, you draw the path first. Reproduce the bug or ask for more information, find the cause, apply a fix, run the tests, route a failing run back to the fix and a passing run on to review, and let only an approval reach done. The agent stays clever inside each node. It just cannot wander off the paths you sanctioned.
The real appeal of the graph is that it is back pressure drawn as a diagram. You trade some of the agent's freedom for mandatory checks and legible failure points, so when a run dies you can point at the node that killed it. You can see the same pattern in LangGraph, in LlamaIndex Workflows, in Jerry Liu's hybrid approach where an outer loop grows parts of the graph as it runs, and in David Khourshid's reminder that this is state machines and the actor model showing up in new clothes. The names differ. The structure does not.
One clarification, because the word is overloaded. A graph here means a predefined directed graph of how the work should flow, conditional edges and all. It is not a knowledge graph. The point is to give the loop a shape you can actually trust.
The Human Did Not Leave. The Human Moved.
Look closely at the factory and you will notice the person is still there. They just moved up the line.
Engineers need to own the outer loop. An agent can reproduce a bug, write the diagnosis, implement the fix, run the tests, and file a report. That is the inner loop, and the agent runs it as well as anyone. But the inner loop was never the job.
The outer loop is the part that stays human. Decide whether this is even the right problem to solve. Verify that the diagnosis and the fix are sound. Approve the change. Carry the consequences of being wrong. The boundary between the two loops is evidence: the diffs, the tests, the logs, and a short explanation connecting them. Strong types, test seams, and explicit rubrics are what let you oversee that evidence without redoing the work yourself.
The clearest way to frame the change is this. You are no longer on the line writing individual changes. You are at the end of the line, designing it and guarding the gate. You can push the model further and make the harness more capable, but spotting problems that grow expensive over years is not something current tools automate away, and the shape of the cost function suggests near-future tools will not either. Execution can be automated. The judgment about whether that execution was correct, and whether it was worth doing at all, cannot.
Robots work fine in the dark. Humans do not. If every corner of the factory floor is dark, and you cannot see the work, and you cannot even find the switch, that is not speed. That is where the danger lives.
Related Signals
More notes from the same corner of the AI layer.