The workflow
A brief becomes issues, an issue becomes a spec, a spec becomes a pull request — the pipeline that ships with the template, and the work that should never go through it.
The boilerplate is the easy half. Every starter in this market ships auth, billing and a dashboard; what none of them ship is a way of working that is already wired up.
brief ──/spec──▶ issues ──/triage──▶ ready ──/task-to-pr──▶ PR ──you──▶ mergedThree commands, four labels, and a rule about which work does not belong here.
The analogy worth holding
Deployments used to be manual. They were stressful, inconsistent, and they broke in ways that depended on who ran them. CI/CD did not make anyone a better engineer — it made the floor the same height for everyone, so a junior's deploy and a principal's deploy were the same deploy.
This is that, one stage earlier. The pipeline does not make an agent smarter. It makes the process the same every time, which is what turns "the agent did something" into "the agent did the steps".
Run one ticket through it
Nothing to configure. These run in your own session.
1. A brief becomes issues
/spec Add CSV export to the invoices list, respecting the current filters/spec reads the codebase before decomposing — a ticket that ignores what
already exists produces a second way of doing something the project already does
once. Then it files GitHub issues with the label vocabulary.
Each issue gets four sections: Outcome, Context, Acceptance criteria, Out of scope.
2. A vague issue becomes buildable
/triage 42For issues that came from somewhere else — a user report, a note to self, a colleague. It reads the code, reproduces where it can, and rewrites the body into the same four sections.
This is the step everything else depends on. An agent given a one-line ticket builds the wrong thing confidently.
3. An issue becomes a pull request
/task-to-pr 42Worktree → outline → build → lq check → tests → e2e if it has pages →
self-review against the acceptance criteria → PR → fix CI.
It never merges. A human decides that.
The labels
| label | means | what moves it on |
|---|---|---|
factory:ready-for-spec | intake — vague, not yet buildable | /triage <n> |
factory:ready-to-implement | acceptance criteria are real | /task-to-pr <n> |
factory:implementing | an agent holds it | the PR opening |
factory:needs-human | an agent stopped, and said why | you |
factory:needs-human is a success. An agent that stops and explains has
saved you reviewing forty minutes of confident wrong work.
Acceptance criteria are the whole thing
Everything above is scaffolding around one idea: work an agent can verify itself is work an agent can do.
Handle deletion sensibly.
produces nothing an agent can check. Whereas:
Deleting is allowed only for
draftinvoices. The server enforces it — a request for asentinvoice returns FORBIDDEN even if the UI is bypassed.
produces a policy module and a test, because it can be checked. That is the entire difference between a pipeline that works and a pile of plausible pull requests.
If you write nothing else carefully, write these.
Turning on the automated path
.github/workflows/factory.yml runs the same commands in CI when a label
changes, so tickets move while you are asleep. It ships disabled.
To enable it:
- Add
ANTHROPIC_API_KEYto your repository secrets - Set the repository variable
FACTORY_ENABLEDtotrue
Both are required deliberately. A key alone is not consent — you may have added it for something else — and until both are present every job no-ops in about two seconds without failing. A workflow that turns every issue red in a repo that never opted in is worse than no workflow.
What it costs: tokens are spent only when a label actually changes. There is no daemon and no schedule, so an idle repository costs nothing.
When NOT to use this
The part people skip, and the part that decides whether the pipeline helps.
Use it for mechanical, well-specified work: a slice whose shape is known, a bug with a reproduction, a migration, a dependency bump, a rule applied across many files.
Stay in the driver's seat for anything where the interesting part is the decision rather than the typing:
- the tenancy or auth model
- a schema change you cannot reverse
- the first slice of a new product area, where the pattern is being set rather than followed
- anything where you would struggle to write the acceptance criteria
That last one is the real test. A ticket you cannot specify is a ticket you have not finished thinking about, and handing it to an agent does not finish the thinking — it moves where you find out.
What this does not claim
It does not remove you. Every serious bug found while building products on this template passed every automated gate — see driving the factory for the list, which includes a date form that silently blanked the field it was editing and a schema transform that would have filed every $12.50 invoice for $1,250.
The pipeline narrows what you have to check. It does not remove the checking.