The Architecture of the Software Factory
Modern software development is shifting from individual coding to building 'factories'—systems of harnessed loops. A loop is a single agentic unit (context, action, check, repeat). A harness provides the environment (sandbox, tools, memory, gates). A software factory is the orchestration of these loops at scale. The fundamental challenge is not generation capacity, but verification. As generation becomes cheap and automated, the bottleneck shifts to the 'review gate'—the expensive, non-scaling resource of human judgment.
Dark vs. Lit Factories
The distinction between 'dark' and 'lit' factories is a matter of human visibility. A 'dark' factory ships code verified only by machines, which can create the illusion of massive throughput. However, this leads to 'comprehension debt'—the widening gap between the amount of code in a system and the amount any human actually understands. While dark factories work for simple, isolated tasks, they fail in complex, long-lived enterprise systems where architectural integrity is paramount. A 'lit' factory keeps humans in the loop for high-stakes decisions, moving judgment upstream to the design and architectural phases before agents begin execution.
Managing Back Pressure and Control Flow
'Back pressure' dictates that an agent should only have as much autonomy as can be cheaply and reliably verified. To manage this, engineers must move from 'vibe coding'—where the model wanders through tool calls—to structured 'graph-based' workflows. By defining explicit nodes and conditional edges (state machines), engineers create a predictable path for agents. This structure acts as a safety net, allowing for automated verification through types, test seams, and well-defined component boundaries.
The Evolving Role of the Engineer
Engineers are no longer just writing diffs; they are now 'outer loop' operators. The inner loop (investigation, implementation, testing) is increasingly automated, but the outer loop (deciding the right approach, verifying soundness, and owning long-term consequences) remains a human responsibility. The most effective strategy is to reserve 'dark' automation for low-risk, high-frequency tasks (like linting or minor refactors) while keeping the 'lights on' for critical systems like authentication, billing, or public APIs where the cost of a wrong decision is high.