The Factory Learns
A dev session planted a deliberate defect to prove a guard could fail, ran the test, and then undid the mutation with a plain git checkout -- on the file. The mutation was gone. So was an unrelated change the same session had made minutes earlier and not yet committed — and the trap was already written in that session’s own memory notes. It had been told. It knew. It did it anyway.
That incident is worth a register entry, and the factory has one. But the interesting part isn’t the loss; it’s the response. Nobody wrote “be more careful with restores” into a document. The item that got filed asks for a tool with a narrow contract: snapshot, assert the mutation landed, run the named test, report, always restore. A day later the tool existed, and the vigilance it replaced was retired with it.
The initial six posts described a factory that builds a product under a harness designed to distrust it. This one is about the change that happened after: the factory became a system that learns from each story. Agents surface friction at the end of every session; the friction becomes an owned item with a written trigger; the next story gets a better tool or a safer boundary. The strong claim is not “the agents improve themselves.” It is narrower and, I think, more useful: an agent may propose a change to the factory, but a human-governed register decides its owner, its trigger and its scope.
(Series rules apply: running totals, never final ones, and every number below is dated and regenerable from the project’s own records.)
- agentFriction surfacesAt the end of a plan, dev, review or QA session, one question: what would have made your life easier?
- agentAn item is filedThe incident, the story, the measurement — and a recommended answer, so the ruling has something to push against.
- DavidOwner, trigger, scopeA human-governed register decides whether it is built, who owns it, and what moment fires it. "Later" is not a trigger.
- agentA narrow toolA testable contract replaces the vigilance. A deliberate tool — never a gate for its own sake.
- registerClosed in the closing sessionThe item moves to the archive with its commentary; the register only ever holds open friction.
↺ the next story inherits the tool — and files the next item
Vigilance Is a Symptom
The pattern behind most of the factory’s recent tooling is the same: a ritual that a session had to remember got performed by hand several times, and then someone asked why it was a ritual at all.
One session had to confirm which story and phase it was working under. The only reliable way was to walk the process tree four levels up to find the agent’s own process and read its environment from the kernel — because the obvious shell command answers for the wrong process and reports a false negative. That ritual was performed by hand at the creation of two consecutive stories. In one of them it caught a real mismatch: a session stamped as development work for one story had been opened with the skill that plans a different story. The register entry that came out of it doesn’t ask anyone to walk the process tree more diligently. It asks for a one-line command that prints the owning process’s attributes, and it carries a sentence I’d frame: every stale-document catch in the previous epic was made by an instrument, never by attention.
The same shape repeats down the register. A QA agent displaced a fixture character the oracle gate depends on, and the gate went red for the next story; the fix on file isn’t “check where the fixtures are” but a declared table of where each fixture belongs, plus a restore command, so the check cannot be skipped. A code review’s status flip pushed a story that failed CI three minutes later on a check that runs locally in under a second; the fix isn’t a reminder, it’s the check wired into the workflow’s own step. In each case the human-shaped answer — vigilance — had already been tried and had already failed, sometimes with the warning in the room.
The rule I’d transport: a repeated manual ritual is evidence of missing machinery. But the register carries the counter-rule too, and it matters just as much: don’t build a gate because you can. The mutation harness item spent a paragraph arguing with itself about whether the tool should ever fail a build, and landed on deliberate tool, never a gate, because a gate demanding the presence of mutations invites filler mutations — the exact vacuity post 4 was about, one level up.
Two Homes and No Register
The register itself was born from a failure, and the failure was a duplication.
Factory improvements had been living in two places. One was a dated markdown file, opened between epics, meant to be absorbed into the next retrospective. The other was the action_items: list inside the sprint status tracker — where every story from epic 5 onward actually filed, because that’s the file a story session has open. Neither list knew about the other. Meanwhile the status tracker’s own preamble had recorded, on four separate occasions, that it had outgrown its stated purpose of loading in one read — about 160% over its size target — and noted that no sweep could reclaim it because every item was open. The diagnosis, when it finally came, is one sentence: the growth was never status lines; it was action items in a status tracker.
I’ve argued elsewhere that duplication is the disease, and this is the disease in its purest form: the same class of fact restated in two files, each file drifting, and the process producing more of both because neither is authoritative. Post 2 found the same shape in the planning corpus, where a decision restated across documents produced contradictions. Here the fix was to give the class of fact one home, and the new file’s own preamble records a detail I find sharp: the dated filename was part of what went wrong. A file called factory-action-items-2026-08-22.md reads as the minutes of one session, not as a living register — which is why the next thirty items went somewhere else. The register has no date in its name, on purpose, and is not scoped to any epic.
There’s a sibling split that’s just as deliberate. Product debt — a missing feature, a packet not yet decoded, a surface not yet built — lives in a deferred work file. Factory friction — a script, a test lane, a gate, a launcher, a document that misled an agent — lives in the factory work file. The split is by subject, not by size, and when an item is genuinely both, it’s filed where its fix lands and cross-linked. That distinction sounds bureaucratic until you’ve watched “improve the QA tooling” and “the quest log doesn’t show progress” compete for the same backlog and lose to each other.
Owner and Trigger
Five rules govern the file — short enough to fit in a table, and the fifth is the one the other four depend on:
The five rules of the factory register
| Rule | What it prevents | In practice |
|---|---|---|
| Every item names a written trigger | Drift. An item without a trigger is a wish. | "Before the next story that declares a byte-identity claim." "The next time a fixture is found out of place." "Only if a review's token cost becomes a stated problem — do not pre-optimize." The last one may never fire, and says so. |
| Every item names an owner | Items nobody picks up. | Me for rulings and anything touching the homelab host; the engineering persona for work inside the repository. "Someone" is not an owner. |
| Ids come from one global sequence | Two items wearing the same number. | Shared with the archive — grep the tree before minting one. |
| A closed item leaves the file in the session that closes it | A register that measures history instead of friction. | It moves to the archive with its commentary intact, so the file only ever grows by open items and its size is a live measure of unaddressed friction. |
| Commentary is the point | Titles without the measurement behind them. | The measurement that justifies an item and the wrong turn it prevents are worth more than its title. What must never be dropped is the trigger. |
This is where “human-governed” stops being a slogan. Agents write most of the entries — they name the incident, the story, the measurement, and often a recommended answer so the ruling has something to push against. But an item that needs a decision says so in capitals and waits. The mutation harness sat as unruled until I answered one question in a chat message. The session-naming item explicitly refuses to be sized until I say which of two things “session” means, because one reading is cosmetic and the other collides with a safety property of the phone launcher. The register is where an agent’s proposal meets a human’s scope.
Two items were born closed on the same day, September 4, inside the code review that filed them: the mutation harness, and a small command that emits the ratified answers a reviewer must not re-litigate. That’s the loop at its shortest — friction identified, tool built, item archived, all within one session — and the second tool’s known limit was filed as a new open item in the same breath, because it reads a story file and the one session that most needs ratified answers is story creation, where no file exists yet.
How this number is measured
Count of open entries in the factory register at the product repo’s tip on 2026-09-04; the archive holds 48 more, 47 done and one in progress. Six items absorbed from the retired dated inbox were carried across without re-verification — re-adjudicating them is the next retrospective’s job.
How this number is measured
An inference from item prose, not a measurement: the register is overwhelmingly incident-fed. The two exceptions are a request to move the phone-button machinery into its own small app, and story-named sessions. Everything else was proposed by an agent from something that went wrong.
How this number is measured
The mutation harness and the ratified-constraints emitter. The register rule that a closed item leaves the file in the session that closes it means they exist only in the archive, with their commentary.
What the Agents Asked For
The channel that feeds the register is almost embarrassingly simple. At the end of a planning, development or review session — and, as of the current story, a QA session — I ask one question, by hand: what would have made your life easier? It isn’t in a skill or a config file yet, which means this post can’t quote a prompt; it can only report that the question gets asked. The mutation harness came out of that question — the restore hazard at the top of this post was the answer a session gave when asked. Items like the linting command the documentation names doesn’t exist and the type checker skips the tests directory are the shape of thing that surfaces this way: friction a session works around silently a dozen times before anyone asks.
Whether that question should be mechanized is, by the register’s own logic, a matter of trigger: the day it’s asked identically for the fourth session type is the day it belongs in the workflow. Until then it’s a human ritual, and this post is one of the places it gets recorded.
The inverse channel exists too, and it was added because of a failure. Epic 5’s retrospective reached its readiness assessment without once asking me how the epic went. The correction that followed is a set of five literal questions the retrospective workflow must now ask before any artifact analysis, and must wait for: how did the epic feel, what was the worst experience (not the worst defect), what am I quietly worried about, what do I think of the product, and which additions earned their keep. The note that accompanies them names the cause with a precision I’d have missed: the cause was not neglect, it was sufficiency. With this much instrumentation, “what went well” is answerable from artifacts, so the run took the audit that was available. But the artifacts record what the agents saw — the operator’s experience exists in exactly one place and cannot be grepped.
Two team agreements came out of that same retrospective, and both belong in the governance post’s rulebook. The first: never optimize the human touchpoint count in either direction. The retro was about to report a drop from roughly eleven touchpoints to eight as a win. It isn’t one; a factory that drives that number down starts excluding the operator, and one that drives it up manufactures ceremony. Report it as an observation. The second is the register’s own immune system: answering a process failure with a new process is the disease, not the cure.
The Biggest Unreviewed Machine
Read the register’s newest items together and a shape appears that no single item states. Five of the 28 are about the code review’s own failure modes:
- Its fix delta gets no adversarial pass. The review applies its patches and stops; nothing re-reads the diff the review itself wrote. During one review the session reordered a prefetch block to fix one thing and, in the same move, silently made an eviction exemption unreachable — caught only because a mutation happened to be run. That’s the two-correct-fixes-one-regression shape, committed by the person applying the fixes. One earlier review delta shipped nine defects. The most recent one was 2,589 lines — a third the size of the story it reviewed.
- Sixteen subagents shared one checkout. Two of them mutated different parts of the tree at once, and one reported that the other’s planted defect nearly made it dismiss a real finding. A red produced by somebody else’s mutation reads as proof. The harness now refuses a second concurrent mutation, which is the safe failure — but it also serializes the one layer that most wants parallelism. Isolated worktrees give both, and the item notes the port collision that awaits anyone who wires that up carelessly.
- It asks for markdown and parses JSON. A format contract that happened to work.
- It doesn’t verify its own gate. Covered above: two commits and two CI cycles lost at one story because the workflow never said “green means green on the head.” Half fixed the same day as an instruction in the workflow’s config — and the item stays open, with the reason stated: an instruction is not an instrument; nothing fails if the session skips it.
- Its subagents re-derive the same context sixteen times. About 2.25 million subagent tokens for one 7,734-line diff, most of it re-reading the same 800-line story file and the same ratified answers. Ranked last on purpose, with a trigger that may never fire, because sixteen independent readings is part of why the layers find different things.
Put those beside the cost data and the shape gets a price. In the September 4 delta window — six stories — review consumed $1,718 of metered compute against $1,995 for development, and its per-story cost ranged from $83 to $507, the widest variance of any phase. Review is the factory’s second most expensive instrument and its least instrumented one. That isn’t a criticism of the review; it found 53 things on the most recent story, 51 of them fixed. It’s the register doing what a register is for: showing where the next mechanism should go, from evidence rather than from unease.
One more item from the same batch generalizes past this project. A hand-edited customization file for one of the workflows failed to parse — one escaping error — and the resolver printed a single warning line, returned the base configuration, and carried on. Every project-specific persistent fact and every activation step silently vanished, and the session proceeded believing it had read the policies. The proposed fix is twenty lines of contract test. The lesson is older than agents: a configuration that fails open is the one failure mode a careful reader cannot see, because the output looks normal.
The Factory, Interviewed
This post was sourced differently from the six before it, and the difference is part of the story.
Until now, each post drew on a snapshot of the product repo’s planning and findings corpus, copied into the blog’s private folder at a dated moment. That snapshot was frozen on August 10, and the factory kept running. Rather than copy it again, the session writing this post opened a message to a live agent session in the product repo — the same cross-session messaging the QA protocol reserves for judgement and operations — and asked ten questions: read-only, answer from files and from the actual query recipes, say not measured where nothing is.
The reply corrected two of my premises. It found that the question I’d described as a prompt didn’t exist in any file (it’s asked by hand — the paragraph above was rewritten because of this). And it found that I’d inverted a safety story about the phone launcher. Then it found something nobody had asked about: the script that attributes findings to the instrument that found them only recognizes the heading style of the first QA report ever written, so five consecutive QA runs had been counted as zero. The next post owes that finding a full section.
It also got one number wrong — a hand count of completed stories, off by one from the regenerable count — and, when asked to re-derive, corrected itself in print rather than deleting the wrong figure, under the same rule this series applies to itself. The delta file that resulted was held out of the repo until the dev session working the tree had finished, because a peer’s message is not an authorization to write, and the interviewed session said so.
I’m telling this not because it’s clever but because it’s the thesis of this post at one remove. The interview surfaced friction — a broken counter, a stale premise, a wrong count — and every piece of it went into a dated file with an owner and a way to regenerate it. The factory learned from being asked about itself. That’s the whole mechanism.
Regenerate This
Documentary again: the factory register and its archive, the retrospective workflow’s customization file (where the operator questions and both team agreements are recorded verbatim), story 6.15’s close-out for the mutation-restore incident and the born-closed items, and the September 4 facts delta for the review-versus-development cost split (its phase query is in the next post). All of it ships when the product repo goes public, and the 28 will be a different number by then — the register only ever grows by open items and shrinks by closed ones, which is exactly what makes its size worth watching.
Final Thoughts
The romantic version of this post is “the agents improve their own factory.” I don’t believe that version, and the record doesn’t support it. What the record shows is agents that are very good at naming friction precisely, measuring it, and proposing a narrow tool — and a human who decides which proposals become mechanisms, when, and under what scope. Remove the register and you get thirty items in two files that don’t know about each other. Remove the human and you get gates for the sake of gates.
The rule I’d carry into any team, with or without agents: when you catch yourself relying on someone’s vigilance for the third time, that’s not a training problem. It’s a missing tool with a testable contract, and the cheapest moment to build it is the one where the failure is still fresh enough to write down as its trigger.
Next: the factory’s tests, layer by layer — which instruments actually find defects, at what cost, and the one instrument that turned out to be lying about the others. That’s The Testing Spine, in two weeks.