Factory Is Not the Product
Factory has moved from running tickets to inspecting, measuring, and repairing its own work. The better evidence is the software coming out the other side.
The last Factory post stopped at 0.3.8. Workers could no longer edit the files that judged them, gate reports recorded the machine they ran on, and District could roll an engine upgrade back without the network.
Sixteen days later, the current release is 0.4.6. The version number is not the interesting part. Factory now has a proper operator surface, a bounded way for another agent to inspect its evidence, and a decision trace that follows a ticket from triage through merge. More importantly, there is software on the other side of it. The pipeline is no longer the only thing worth writing about.
Factory got a front door
Factory 0.4.0 replaced the old dashboard with an outcome-control workspace. It shows live flow, cases that need attention, retained outcomes, the codebase map, and the ticket-flow reference in one place. Its readers are bounded and report gaps instead of quietly treating partial history as complete.
It also added factory mcp: a stdio MCP server that lets one external agent inspect the registered repositories through the same evidence commands as the workspace. The first release exposed reads only. 0.4.1 added three named human actions—re-queue an agent, resolve and close, or send a ticket back to triage—with the same input checks in the browser and MCP. A write is prepared, shown for confirmation, checked again against the live target, and then applied. There is no generic “run a command” tool hiding behind it.
That distinction is where most of the work has gone. An agent can ask what happened without getting a shell. It can propose one of three things without being allowed to improvise a fourth. The useful surface is not chat. It is the narrow contract behind the chat.
The factory started watching itself
The other half of 0.4.1 is less visible. OMP worker transcripts now survive by ticket. Every escalation gets a mechanical code as well as prose. factory score reads those transcripts and records tool calls, edits, retries, first-pass gate results, and two deliberately limited judgment scores. If the judging model is unavailable or does not return a valid number, the score is null. It is not guessed.
factory watch reads local runtime evidence after a pass and files a bug when Factory itself breaks. The first week was useful in an unflattering way. The monitor filed bugs for several conditions that were not defects at all: a journal hitting its intentional event bound, an audit row sharing the lifecycle log, and a passive process reader honestly saying that it had not scanned descendants. Worse, each install filed engine failures into the project it happened to manage. Forty-six Factory bugs landed in the rocm-cli, rocm-app, District, and GPUFlo trackers between October 16 and 19.
Factory 0.4.3 fixed the ownership error. Every install now sends engine failures to Factory's tracker, deduplicates the same failure across the fleet, and treats unknown reader codes as evidence gaps rather than defects. That is a better result than a clean demo. The monitor watched the monitor, produced noise, and the noise turned into narrower rules.
factory learn also mines the lowest-scored retained sessions instead of the last forty lines of a worker log. Repeated tool calls and failed operations are more useful lesson material than a closing paragraph that says everything went well. The newest work on main lets reviewed lessons merge automatically, then reverts them if the next scored window falls beyond the recorded baseline noise.
One smaller change matters just as much. Tests used to be fully protected, which meant a worker needed a human override even to add a regression test. Factory now has add-only protected paths: an agent may add a test or append lines, but it still cannot delete, rename, or alter an existing test without the override. That is a much better rule than choosing between “agents may edit tests” and “agents may not write tests.”
The release loop joined the pipeline
Factory 0.4.2 added automatic patch-release PRs. A release needs new CI-green code, a passing release-only gate, enough finished tickets, and a quality bar no worse than the last reachable version. The first implementation could tag a release without publishing its GitHub Release, so 0.4.2 sat behind 0.4.1 on the Releases page until Michael fixed it by hand. Version 0.4.4 made publication part of factory release.
Version 0.4.6 closes two more mundane gaps. A release PR now updates the version, changelog, fixed install pins, project-page date, and public history together, and refuses the release if any expected spot is missing or duplicated. It also adds factory explain N, a bounded decision graph built from structured records for triage, binding, scheduling, worker choice, gates, review, manager actions, merge, and learning. It includes costs and coverage gaps. It does not reconstruct decisions the journal never recorded.
What the machinery is for
The projects around Factory do not look like five versions of the same agent demo.
GPUFlo is a small Rust terminal instrument for AMD GPUs. It reads the Linux amdgpu interfaces directly, stays read-only, and gives every unavailable metric a reason instead of displaying a fake zero. Factory has maintained it since the 0.1 releases; the current 0.2.1 release added a terminal-native theme and fixed a firmware bit that made idle RDNA 3 and RDNA 4 cards look permanently thermally throttled.
District runs the host around the pipelines. It owns the registry, engine version, ports, systemd units, upgrades, rollback, and fleet status. Factory decides what happens inside one repository. District makes sure five copies do not each invent their own answer to the same machine-level problem.
Benito is the outlier, and the most ordinary product in the group: a self-hosted baby tracker for iPhone, iPad, and Apple Watch. A small Rust server and SQLite file keep one family timeline in sync. The app tracks feeds, sleep, diapers, medicine, walks, car rides, and crying; running timers appear on the Lock Screen and Watch. The latest work replaced shared passwords with one-time family invites and per-device keys, added expiring caregiver access, and prepared the repository for open source. It is still private, and it is not managed by Factory yet. I am including it because the point of the machinery is to help build software people actually use, not to produce more machinery.
rocm-cli sits at the other end of the story. It is AMD's tech-preview single binary for setting up and running local AI on AMD GPUs, with model serving, telemetry, and chat. The bespoke issue-to-agent loop built around its development was lifted out into Factory on September 2. Our fork is now managed by Factory and kept aligned with the public upstream. Factory did not create rocm-cli; rocm-cli created the need for Factory.
Factory itself and District round out the five projects on the new Projects page. That page is intentionally short. The repositories and the field notes can carry the details.
Receipts, not a victory lap
There are still sharp edges. The stable release is 0.4.6; automatic lesson promotion and reversion landed on main after it. A score from a model is a recorded opinion, not a quality metric. Benito is not public. District still draws a hard line around host administration, and Factory's worker launch prefix is still not a sandbox.
But the balance has changed since the first Factory post. In September, the evidence was that the loop could build itself. Now it maintains a GPU monitor, operates its own host layer, keeps a large upstream fork moving, and has enough retained evidence to catch the tool's failures after shipping. The next useful measure is not how many tickets Factory can close. It is whether the software outside the pipeline gets better without making the person running it guess what happened.
The views expressed here are my own and do not represent AMD.