I wrote my development workflow down as skills so I could ship more with less of my time. Each skill tells an agent how to do one step of the software development lifecycle (SDLC), from planning to building, reviewing and shipping. But skills only describe the steps. I still had to run the workflow myself, starting each step, carrying context from one to the next and checking that the agent actually did what the skill asked.
To scale, I need to trust the output without watching every step. Tell an agent not to change a failing test just to make it pass, and it will usually listen. That is good enough when I watch every session. It is not good enough when several agents run at once and I only read what they hand back.
So I converted the workflow into code. dim-factory runs the SDLC for me, and it is built to earn that trust. The main idea is simple: the skills tell an agent how to do the work, and the way the factory starts the agent decides what it is allowed to do.
The record and the factory
dim-factory is a command-line tool that coding agents use to run my workflow. It has two parts: the record and the factory. Both keep their data in a local database on my machine.
The record reads the transcripts of every coding agent I use, Claude Code, Codex, Grok Build and Pi, along with the git history of the repos they worked in. It never calls a model and never touches the network. It does not filter or score anything on the way in, so I can ask new questions of old sessions later.
The factory runs the work and keeps track of every order. It can look things up in the record, so an agent can check what was already done before it starts.
Who decides what
Some steps in building software need someone to think, and some do not. Setting up a fresh copy of the code, running the tests, rebasing and merging are the same every time, so the factory does them itself. Deciding what to build, how to build it and whether it is good enough takes thought, so that goes to me or to an agent.
I keep that line strict. The factory never tries to fake a decision with a clever rule, like scanning a commit message for certain words. A rule like that only handles the cases I thought of when I wrote it.
The automatic checks work the same way. They only catch what you cannot see by reading the code: whether the tests really passed on the code that was committed, and whether the agent changed the tests to make them pass. Things you can see by reading, like a stray comment or a sloppy commit message, are left to the reviewer.
An order’s path
From my side, the factory is one skill. In my own Claude Code session I run /dim-factory and describe the work, and it turns that into an order and runs it. An order is one piece of work: a title, a description and the repo it belongs to.
With /dim-factory loaded, the agent in my session becomes what dim calls the operator. It runs the order through three stations, plan, build and review, and brings each result back to me. It never does the work itself.
The work is done by workers. Each station of an order gets its own worker, a named identity like latch-42 that carries the context for that station. A worker runs in a Claude Code session, but the session is only what carries the context right now. If the session dies, the factory starts a new one for the same worker with the same context, and the worker carries on where it stopped.
Each worker starts from a short brief with the facts of the order, and the skill for its station tells it how to do the work. The station skills are based on my own plan, build and review skills. Every station ends with an artifact, a document written for me:
- plan reads the order’s description and returns the Plan artifact, which breaks the work into small steps that dim calls slices
- build reads the approved Plan artifact, commits each slice through the checks, answers any review comments and returns the Build artifact
- review reads the approved Build artifact and the full diff, and returns either the Review artifact or comments for the builder to answer
A station is done when the factory says so, not when the worker says so. A worker that hands back something incomplete gets one more try before the station fails.
I approve or send back each artifact before the order moves on. I read them on the wall, a small local board that shows every order, instead of reading the diff. I never tell the factory which station to run next. It works that out from the record.
One log per order
Everything that happens to an order is written to a single log, and nothing in it is ever changed or deleted. Each entry says who did it: which worker and session, or the factory itself. The order’s status, its plan, its review comments and what it is allowed to do next are all worked out from that log rather than stored separately.
This makes the factory predictable for the agents that use it. If the operator tries something the order does not allow right now, the factory refuses and lists what it would accept instead. Every error also says which command fixes it, so the agent reading it does not have to guess.
When something fails, the reason goes into the log before the error is shown. If an order is stuck, I can see why in the record, even after the terminal that ran it is long gone.
The log also overrules git. If the order’s branch has a commit the log does not know about, the factory moves the branch back and leaves the changed files in place. That one rule covers a rejected commit, a crash halfway through and an agent rewriting history.
Locked down at start
Each worker runs in a separate Claude Code process that the factory starts with a specific setup:
- its own home directory, so none of my settings, skills or credentials reach it
- only the environment variables it needs, such as its own sign-in, and nothing else from my environment
- a sandbox where the builder can write only to the order’s copy of the code, and the planner and reviewer can write nothing outside a scratch folder
- no network, except a single local connection back to the factory
- the factory’s own skills, and nothing from the repo that could add hooks or change its settings
- the model I picked for its role
The worker cannot touch the factory’s database directly. To record anything, such as a finished slice or its artifact, it has to send it through that one local connection, and the factory checks it before writing it down. Once the worker’s process ends, the connection closes and nothing more gets in. It also cannot change the repo’s git hooks or settings without failing its station.
The factory also never takes a worker’s word for who it is. It looks at which process actually started the command, so a worker cannot claim to be the operator just by setting a variable.
I will be honest: for one person’s projects this is a lot of machinery. But every item on that list replaced an instruction I would otherwise have written into a skill and hoped the agent followed.
Commits and shipping
The builder commits with plain git commit and then hands the commit to the factory. The factory keeps it only if all of these hold:
- it is exactly one new commit on top of the last one the factory accepted
- it does not change the project’s check, such as its test script
- there are no other changes left lying around in the working copy
- the project’s check passes on that exact commit
- running the check does not change any files, which catches things like a formatter that was not run first
If any of these fail, the commit is taken off the branch, the files stay so the builder can fix them, and the reason is logged along with the check’s output.
The check itself is whatever the project already uses to verify a change, such as pnpm verify. The factory runs it on a clean copy of the code in a macOS sandbox that can only write to that copy, with no credentials, and stops it after ten minutes.
When I approve the Review artifact, the factory ships the order on its own. It rebases the work onto the main branch, runs the check again and moves the main branch forward in a single step. So the main branch gets all of the order’s commits or none of them. A conflict or a failing check sends the order back to the builder.
Safe to kill
Any part of the factory can crash or be killed at any moment without leaving a mess. The next time the order runs, the factory cleans up whatever does not need a decision: it stops leftover processes, finishes judging a commit that was handed in but never checked, removes commits the log does not know about and retries a ship that was cut off.
The factory keeps a copy of every worker’s transcript, so when a session crashes or hits a usage limit, the worker’s new session starts from that copy. The log notes what happened, including when the usage limit resets.
I test this by running the same order many times while killing processes at random points. Every run has to end with the order shipped or with a clear problem reported, and nothing recorded twice.
Lights still on
Some of the design is not in the code yet, and I have not measured whether any of it saves me time. These are the biggest gaps:
- earned trust: the record should show which kinds of work I have stopped needing to read, so those can skip my approval, and a single bad result should take that trust away again
- pull requests: shipping only works by moving the main branch directly, so repos that merge through pull requests have to wait
- picking work: the factory does not pick its own work yet, so I still start every order myself
- other harnesses: workers only run under Claude Code for now, and the plan is to add others, such as Codex, through the same adapter the factory uses to start Claude Code
You do not need dim to use the main ideas. Keep one log per piece of work and work everything else out from it. Only automate the checks that reading the code cannot do. And decide what an agent may do by how you start it, not by what you put in its prompt.