Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions .claude/skills/factory-operator/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
name: factory-operator
description: Use the software factory to create, assign and monitor a task. Use when a coding agent needs to hand work to the factory, label an issue factory:ready, or read what the factory is waiting on. Not used by the factory's own stages.
---
<!-- Ported from owainlewis/machinist@3943516 skills/machinist/SKILL.md:1-75 (MIT, Copyright (c) 2026 Owain Lewis). Deviations: machinist run/submit become the factory:ready label; status comes from factory inbox and factory logs. -->

# Factory operator

The factory turns a GitHub issue into a planned, built, independently verified pull
request. It never merges the pull request.

## Core model

- A task is one GitHub issue in the target repository.
- Assigning a task means labelling the issue `factory:ready`. The watcher picks it up.
- Label the same issue again to continue interrupted work. The factory reuses the existing
branch, worktree and pull request.
- When `FACTORY_ISSUE` is set, you are already inside a factory run. Follow the assigned
stage and do not label or start another run.

## Create a task

Reuse a supplied issue when it is open and belongs to the current repository. Otherwise
create one issue with `gh issue create`. Keep it focused on one observable outcome and keep
the user's constraints. Do not invent implementation details the request does not decide.

```sh
gh issue create --title "<short outcome>" --body "<problem, outcome, constraints, and acceptance evidence>"
```

Use the issue URL that GitHub returns for every later command.

## Assign a task

```sh
gh issue edit <N> --add-label factory:ready
```

The label has no effect unless a watcher runs for this repository (`factory doctor` says
whether the loop can run).

## Report status

```sh
factory inbox --repo <owner/name> --json
factory logs <N> --repo <owner/name> --json
```

The inbox lists what waits for a human. The logs show one run's events, one JSON object per
line. Then read the linked pull request and its checks.

- For blocked work, fix the reported cause or answer the question, then comment
`/factory retry` on the issue.
- For completed work, hand the pull request to a person. Never merge unless that person
explicitly decides to.
- Approving a plan (`/factory approve`) is a human decision. Do not post it on their behalf.

When reporting status, include the issue URL, the pull request URL when there is one, the
checks, and the blocker or next human action.
19 changes: 19 additions & 0 deletions .factory/config.example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"repo": "owner/name",
"base": "main",
"baselineTag": "baseline",
"gates": [
{ "name": "test", "cmd": "TODO: the command that runs your tests, e.g. make test", "required": true },
{ "name": "lint", "cmd": "TODO: optional, e.g. make lint", "required": false }
],
"agentCommands": {
"read": [],
"build": ["TODO: the commands the builder may run, e.g. make *"],
"verify": ["TODO: the commands the verifier may run, e.g. make *"]
},
"protectedPaths": [".factory/**", ".claude/**", ".agents/**", ".github/**"],
"riskPolicy": { "autoApproveLowRisk": true },
"maxOpenFactoryPrs": 3,
"concurrency": 3,
"pollIntervalSeconds": 15
}
32 changes: 32 additions & 0 deletions DEMO.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,35 @@ reset puts `main` back on the baseline. The factory never merges.

`main` is protected, so rewinding it needs "Allow force pushes" on for you (Settings, Branches). Turn it on
first; if it is off the reset fails on its first push and changes nothing. Turn it off again afterwards.

## By release

Each section names one thing to show for that factory release. Run them from `../factory`.

### v2.3: the boundary tells the truth

Label "README has no run steps" `factory:ready`, then comment `/factory cancel` while it waits for plan approval.
The issue closes, the PR (if any) closes, and the worktree is gone. Then `bin/factory doctor --repo-dir ../splitbill --json`
shows every check and exits 4 if one fails.

### v2.4: the cockpit

`bin/factory inbox --repo-dir ../splitbill` lists what waits on you. Acting from the dashboard Inbox or with
`bin/factory inbox 12 approve` posts the same `/factory approve` comment you would type. `bin/factory logs 12 --follow`
tails the run.

### v2.5: any agent, counted honestly

Run the cent-split issue and open Analytics: each stage shows its agent, tokens and cost. A stage whose agent reports no
usage shows "Not reported", never $0.00. Read-only stages (triage, plan, verify) cannot write files.

### v2.6: one factory, any agent

Open the Agents page: each preset, its pinned version, the installed version and its doctor rows. Add a second agent under
`agents` in `.factory/config.json` and point `stages.verify` at it. `bin/factory install --update` (or `install.sh --agents`)
links the skills into that agent's own directory.

### v2.6.1: presets that work on first use

`bin/factory verify-agent <name> --repo-dir ../splitbill --issue <N>` runs one issue on that agent and records a fixture.
Only Claude is verified by the maintainers; the rest say "Verified by participants: not yet" until someone does.
Loading