Building a Dark Software Factory
A practical way to let approved software work move overnight, while people keep hold of direction, risk, and final approval.
TL;DR
A Dark Software Factory is not one model left alone to write code all night.
It is a governed production system. Plans become bounded tasks. Agents pick up approved work on a schedule. Checks produce evidence. People stay responsible for direction, risk, and final approval.
The loop is straightforward:
Plan moves to Queue, then Execute, Verify, Review, and Learn. The learnings improve the next plan.
The models are getting better at working for longer stretches and working in parallel. The tougher job is the system around them: persistent state, clear permissions, reliable checks, and the discipline to stop when a decision belongs with a person.
From dark manufacturing to dark software
A dark factory is built to keep operating with very little activity on the production floor. Machines do not need lights, breaks, or a normal shift pattern. Sensors, industrial software, and remote monitoring keep the work moving.
Even there, most companies do not jump straight to total autonomy. They automate particular cells or shifts first, especially where the work is repeatable. Complex products and frequent variation still need people close to the process.
Software needs the same distinction.
A Dark Software Factory is not about removing people from development. It is about removing the need for people to supervise every execution step. People set intent, priorities, constraints, and acceptable risk. Agents take on repeatable planning, implementation, verification, reporting, and maintenance inside those boundaries.
The goal is not to replace a team with one autonomous model. It is to let approved software work continue safely without somebody having to keep prompting it.
The three foundations
1. Plans that turn into real work
Every run starts with a plan. But “build the app” and “improve the codebase” are not things an agent can responsibly finish. They have to become work units with a clear outcome, boundary, owner, and way to prove they are done.
Vision
Product outcome
Initiative
Feature or improvement
Executable task
Acceptance checks
A good task answers a few practical questions:
- What has to change, and why?
- What must stay untouched?
- Which part of the system is affected?
- What evidence proves it is complete?
- Which decisions need a human sign-off?
- How can we abandon or roll it back?
The first product request can stay high level. It should talk about users, outcomes, and constraints. Before execution, though, the task needs to be specific enough that completion does not depend on anyone guessing.
Good factory tasks are bounded, testable, owned by one agent at a time, reversible, and small enough for someone else to review. The broad plan gives direction. Small tasks give the factory something it can actually carry.
2. Guardrails that produce evidence
Prompts influence behaviour. Guardrails enforce it.
“Use good judgment” and “keep this maintainable” are useful intentions, but they are not proof. A reliable system turns expectations into checks that run.
- Unit, integration, and end-to-end tests
- Type checks, linting, formatting, and production builds
- Dependency, security, and migration validation
- Architectural boundary and file ownership rules
- Accessibility and performance budgets
- Diff and task-size limits
The point is evidence. “Do not break the app” becomes “the existing unit suite, affected browser scenarios, type check, and production build must pass.” “Follow the codebase structure” becomes “inspect the local instructions and nearby module before proposing an abstraction.”
Skills can make repeatable engineering habits easier to reuse. Repository instructions can explain local conventions. Tests and static checks hold the line where we do not want to depend on a model’s judgment.
Guardrails also set authority. Not every run should be able to do everything.
| Level | Authority |
|---|---|
| 0 | Inspect and report |
| 1 | Create plans and tasks |
| 2 | Modify an isolated worktree |
| 3 | Run checks and create a commit |
| 4 | Open a pull request |
| 5 | Merge or deploy after human approval |
Destructive, expensive, security-sensitive, or externally visible actions deserve explicit approval. The factory is not safe because the model is clever. It is safe because its authority is limited.
3. A board that acts like the factory floor
In this model, the board is more than project management. It is the persistent state that connects planning, execution, review, and recovery.
Idea → Needs specification → Ready → Claimed → In progress
→ Verification → Human review → Done
It also needs honest exits: Blocked, Needs decision, Failed, and Retryable. A useful board can tell us what is ready, who owns it, when it was claimed, where the work lives, which checks have run, what failed, what decision is waiting, what it cost, and what should happen next.
Linear, Paperclip, and a custom internal harness can all serve this role. The important contract is simpler than the tooling: work needs to live as persistent, claimable, inspectable state outside a model conversation.
Without that state, we do not have a factory. We have a pile of disconnected sessions.
The factory loop in practice
The useful separation is between artifacts, not just agent turns. Planning creates a specification. Breakdown creates bounded tickets. Execution creates code and an activity trace. Verification creates test evidence. Review creates findings and a verdict. The final outcome updates the product and improves the harness.
An executor should not be the only judge of its own work. A reviewer needs the original requirement, fresh context, and permission to disagree with the implementation.
People still own product intent, priorities, taste, risk appetite, security-sensitive decisions, architectural exceptions, budgets, and consequential approvals. Agents are very good at clarifying specifications, exploring repositories, changing code, running tests, reproducing bugs, preparing pull requests, writing docs, and producing the first pass of a review.
That shifts people toward direction and judgment instead of making them the handoff point for every mechanical task.
Let the day and night do different work
There is a rhythm that feels natural here.
During the day, people explore ideas, choose product direction, resolve ambiguity, approve specifications, prioritise tasks, and make meaningful decisions.
At night, agents pick up approved tasks, work in isolated environments, run checks, inspect failures, review results, and prepare clear summaries.
The morning handover should not be a stack of transcripts. It should say what finished, what passed, what failed, what is blocked, what needs approval, and what the factory suggests doing next.
That is a much better use of overnight execution: a structured shift handover, not an unattended gamble.
Start with a narrow lane
The fastest way to create trouble is automating every stage at once. Start with one lane that is easy to observe:
Approved bug → isolated execution → regression test → implementation
→ affected checks → review summary → human merge
When that is boring and reliable, add another: board triage, specification, task breakdown, human approval, then execution. Later, add recurring maintenance, independent reviews, automated pull requests, and low-risk merge policies.
Useful recurring shifts can look for bugs in logs and failed tests, turn accepted ideas into specifications, triage incomplete work, rerun flaky checks, and prepare release or project summaries. The important default is restraint. A maintenance shift should create proposals before it starts rewriting the codebase.
Give each task only what it needs
Tools, skills, MCP servers, memories, and repository instructions all take attention. Giving every task the entire company catalogue does not make an agent more capable. It makes choices slower, authority harder to read, and mistakes easier to make.
Put a capability router between the queue and the execution environment. At first it can stay deterministic:
Task type → capability bundle → allowed tools → permission level
Ask what kind of task this is, where it belongs, which skills apply, which tools it needs, what it is allowed to change, which model fits, and what time and budget it gets. Expose the smallest useful set of capabilities. Ambiguous routing can come later.
What this experiment keeps teaching me
The model is rarely the whole system. The quality of the factory comes from task decomposition, persistent state, clear permissions, executable guardrails, independent review, visible failures, a good approval interface, and the ability to stop rather than guess.
Long-running agents make this possible. The harness makes it dependable. The board gives it continuity. Guardrails make the work reviewable. People give it purpose.
The future here is not people versus agents. It is people providing ideas, direction, judgment, and approval while agents provide scalable planning, execution, verification, and repetition.
Use the day to decide what is worth building. Let the night do the bounded work.
References and tools
- Siemens on lights-out and lights-sparse manufacturing
- OpenAI Codex for long-running tasks, multi-agent work, skills, and scheduled automation
- DevSpace for local repository access through MCP-compatible clients
- Linear Codex integration for delegating board issues to coding agents
- Paperclip for persistent, governed multi-agent orchestration
- Matt Pocock’s Engineering Skills for composable engineering workflows
- Model Context Protocol for tool schemas, permissions, consent, and external-system integration
This is an ongoing personal experiment, not a claim that fully autonomous delivery is universally reliable. The useful version is smaller: a software production system where people keep the steering wheel and agents make approved work move.