agentleFS
momoathomemomoathome/software-factory/skills/factory/SKILL.md

factory

Skill0 starsChanged 13 days agoMITView on GitHub

Run the software factory. Use when the user types /software-factory:factory (or /factory) with <feature>, a Linear issue key (ABC-123), next, approve <job-id>, or rework <job-id> <note>. The session that runs it becomes the orchestrator of the spec → build → review → approve → developer review loop.

  • Commits and pushes

15 other projects use a version of this.

Adopted by

Most recently taken up by

Used with

Projects with it also use status and implement.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • AnthropicSkill

    status

    Case status summary by audience — client-facing (plain language), internal (for the professor), or court-ready (formal caption format per local rules). Same facts, different framing and depth. Use when a student needs to update the client, brief the professor, or prepare a court status report.

    Also in 3 projects that use this

  • Hugging FaceSkill

    implement

    Make tests pass. Invoke after /write-tests produces failing tests.

    Also in 3 projects that use this

The file

Show its rules and text

We split this skill into the rules it gives an agent

28 rules. 0 are common, 7 are distinctive, and 21 are very specific to this project.

  • 0

    Common

    Most of the 14 edited versions we read keep these.

  • 7

    Distinctive

    This author's own choices. Worth a look.

  • 21

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Every agent reads AGENTS.md (or CLAUDE.md) for the repo's setup, dev server, validation commands and conventions.

    line 45
  2. Very specific:

    Every job runs in its own git worktree on its own branch, so several jobs can run at once, one per Claude session.

    line 66
  3. Distinctive:

    Only Merge touches it.

    line 73
  4. Very specific:

    Run this first on every /factory command.

    line 102
  5. Very specific:

    Every agent prompt starts with the job's absolute paths: Job folder: <repo>/factory/jobs/<job-id>/.

    line 146
  6. Distinctive:

    Prepare the repo: Only the first time in a repo:

    line 156
  7. Very specific:

    If factory/dashboard.html is missing, mkdir -p factory and copy ${CLAUDE_PLUGIN_ROOT}/templates/dashboard.html there.

    line 157
  8. Very specific:

    If factory/backlog.md is missing, copy ${CLAUDE_PLUGIN_ROOT}/templates/backlog.md there.

    line 159
  9. Very specific:

    If git check-ignore -q factory/jobs/x fails, append /factory/jobs/ to .gitignore and tell the user to commit it.

    line 161
  10. Very specific:

    If git rev-parse --verify <base> fails, stop and tell the user to set Base branch: in AGENTS.md.

    line 163
  11. Very specific:

    Worktree: Create the branch and its worktree from <base>:

    line 175
  12. Very specific:

    Wait for it to finish, then check that spec.md exists.

    line 185
  13. Distinctive:

    Wait for it to finish, then go to Build check.

    line 188
  14. Very specific:

    Read the first line of build.md.

    line 192
  15. Very specific:

    UI check: Run git diff --name-only <base>...factory/<job-id> in the worktree.

    line 201
  16. Distinctive:

    Check again every round, since a fix can touch the UI.

    line 210
  17. Distinctive:

    Never resume the builder mid-round.

    line 218
  18. Very specific:

    Any CHANGES, no resumes left: write decision.md yourself, reading ESCALATE, then a blank line, then Review rounds exhausted.

    line 226
  19. Very specific:

    When it finishes, check that the first line of decision.md is APPROVE or ESCALATE (otherwise stop and tell the user), then go to Developer …

    line 234
  20. Very specific:

    Run the per-job teardown from the ## Factory section of AGENTS.md, if there is one (a failing teardown doesn't block the PR.

    line 262
  21. Very specific:

    Write factory/jobs/<job-id>/pr.md as the PR body: the feature in one or two sentences, Fixes <issue key> on its own line when the job has …

    line 268
  22. Very specific:

    Write the PR URL that gh prints to job.json as pr and set stage: "pr-open".

    line 280
  23. Very specific:

    Run /factory <item>, and once step 1 has given it a job id, replace claimed on its backlog line with the job id.

    line 318
  24. Very specific:

    When the argument is a Linear issue key (^[A-Z][A-Z0-9]*-[0-9]+$, for example ABC-123), fetch the issue and claim it (see Linear).

    line 323
  25. Distinctive:

    Updates: Keep the issue in step with the job, each as one MCP call:

    line 353
  26. Very specific:

    Write the note, verbatim, to factory/jobs/<job-id>/rework-<k>.md, where k is the next unused number.

    line 376
  27. Very specific:

    Keep the user posted with one short line per transition, for example 003-rate-limiting: round 2, security CHANGES, ux/ui/code PASS → …

    line 386
  28. Very specific:

    When the loop stops, say that the job waits in dev-review and why.

    line 388

“Common” is measured: kept by at least 6 in 10 of the 14 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Factory

You are the orchestrator for one job. You run the loop below, spawn every agent, and are the only writer of your job's job.json. You never write code, specs, reviews or decisions yourself, apart from the fixed texts this file spells out. Agents do the work and each writes one file; you move the job along and keep job.json current.

The loop

feature → spec-writer → builder → [security, ux, ui, code] → WAIT FOR ALL
                           ▲                                      │
                           └──── any CHANGES: resume builder ◄────┤
                                                                  ▼ all PASS
                                                    approver (APPROVE | ESCALATE)
                                                                  ▼
          deliver (merge or PR) ◄─ /factory approve ─ dev-review ─ /factory rework → builder

Nothing is delivered until the developer has looked at it: every job ends in dev-review, and only /factory approve merges or opens the PR. The approver only recommends.

StepAgent (subagent_type)Writes
specsoftware-factory:spec-writerspec.md
buildsoftware-factory:builderbuild.md + commits on factory/<job-id>
reviewsoftware-factory:reviewer-securityround-N/review-security.md
software-factory:reviewer-uxround-N/review-ux.md
software-factory:reviewer-uiround-N/review-ui.md
software-factory:reviewer-coderound-N/review-code.md
approvesoftware-factory:approverdecision.md (recommendation + notes)

MAX_RESUMES = 2: after round 1 the builder can be resumed at most twice, so a run has at most 3 review rounds. The agents ship with the software-factory plugin, so every subagent_type carries the software-factory: prefix. To change the factory, edit this file and agents/ in the plugin repo, not in the project.

Every agent reads AGENTS.md (or CLAUDE.md) for the repo's setup, dev server, validation commands and conventions. Nothing repo-specific lives in these files. A ## Factory section in AGENTS.md, when present, holds what the factory needs beyond that: per-job setup and teardown, ports, test accounts, and paths that always escalate. It overrides the defaults in these files.

<base> is the branch jobs start from and merge into. Take it from a line Base branch: <name> in AGENTS.md (or CLAUDE.md); without one it is main.

Two more lines in AGENTS.md choose how work comes in and goes out:

  • Delivery: merge (default) merges approved jobs into <base> locally and never pushes. Delivery: pr pushes the job branch and opens a GitHub pull request against <base> instead; humans review and merge it on GitHub. It needs gh logged in (gh auth status).
  • Task source: backlog (default) makes /factory next read factory/backlog.md. Task source: linear makes it take the next Linear issue instead, see Linear.

Parallel jobs

Every job runs in its own git worktree on its own branch, so several jobs can run at once, one per Claude session. To run three features, open three sessions in this repo and start /factory in each. Your session orchestrates only the job it started or was handed.

  • Your session stays in the main checkout. Agents work in the job's worktree. The main checkout is the user's, and it may be dirty or on another branch. Only Merge touches it.
  • Job state lives in factory/jobs/<job-id>/ in the main checkout, never in a worktree. Each job has its own job.json, so sessions never write the same file.
  • Each job gets its own dev server ports and agent-browser sessions (see Prompts), so reviewers of different jobs never see each other's pages.

Files

<repo> is the main checkout (git rev-parse --show-toplevel from your session) and <name> is its folder name. factory/jobs/ is gitignored runtime state that never lands in a commit.

<repo>/factory/backlog.md                      queue for /factory next
<repo>/factory/jobs/<job-id>/job.json          the job's state (you write it, the dashboard reads it)
<repo>/factory/jobs/<job-id>/spec.md
<repo>/factory/jobs/<job-id>/build.md
<repo>/factory/jobs/<job-id>/rework-<k>.md     written by you, from /factory rework
<repo>/factory/jobs/<job-id>/round-<N>/review-{security,ux,ui,code}.md
<repo>/factory/jobs/<job-id>/decision.md
<repo>/../<name>-factory/<job-id>/             the job's worktree, on factory/<job-id>

Job folders are never deleted by the factory. Once a job is merged or closed nothing reads its folder again, so the user may delete it.

PR sweep

Run this first on every /factory command. Jobs in pr-open have no orchestrator any more, so this is the one place where you write a job.json that isn't your job's. For each factory/jobs/*/job.json with stage: "pr-open", run gh pr view <pr> --json state -q .state:

  • MERGED: set stage: "merged".
  • CLOSED: set stage: "closed".
  • OPEN, or gh fails: leave it.

The per-job teardown already ran before the push, and Linear closes the issue through Fixes <key>, so there is nothing else to do. Report changes in one line, for example PR sweep: 001-french-locale merged., and say nothing when nothing changed. Only jobs in this checkout's factory/jobs/ are swept: each developer's factory sees only the PRs it opened.

job.json

{ "id": "003-rate-limiting", "feature": "Rate limit the signup form",
  "issue": { "key": "ABC-123", "url": "https://linear.app/…/ABC-123" },
  "pr": "https://github.com/org/repo/pull/42",
  "branch": "factory/003-rate-limiting",
  "worktree": "/Users/you/code/my-app-factory/003-rate-limiting",
  "stage": "dev-review", "round": 2, "decision": "APPROVE", "head": "4f2c1ab",
  "reviews": { "security": "CHANGES", "ux": "PASS", "ui": "pending", "code": "PASS" } }
  • stage is one of spec, build, review, approve, dev-review, pr-open, merged, closed (PR closed without merging). Worktree setup counts as spec.
  • decision is the first line of decision.md (APPROVE or ESCALATE), set when the job enters dev-review and decision.md exists; drop it otherwise.
  • head is git rev-parse factory/<job-id> when the loop hands the job to dev-review. A failed Deliver keeps it. Commits after it are the developer's own.
  • issue is set only for jobs started from a Linear issue, pr only once a pull request exists.
  • round is the current review round (0 until the first round starts).
  • reviews holds the current round only. Each value is pending, PASS or CHANGES. Earlier rounds live in their round-<N>/ folders, which the dashboard reads directly.
  • Rewrite the whole file on every change. worktree is always an absolute path.

Prompts

Every agent prompt starts with the job's absolute paths: Job folder: <repo>/factory/jobs/<job-id>/. Worktree: <worktree>. Branch: factory/<job-id>. Base branch: <base>. Below, <paths> stands for that sentence.

Agents that open pages also get a port. With n the job number (003 → 3), the builder gets 5100 + 10n, reviewer-ux gets 5101 + 10n and reviewer-ui gets 5102 + 10n, appended as Port: <port>.

/factory <feature>

  1. Prepare the repo. Only the first time in a repo:
    • If factory/dashboard.html is missing, mkdir -p factory and copy ${CLAUDE_PLUGIN_ROOT}/templates/dashboard.html there.
    • If factory/backlog.md is missing, copy ${CLAUDE_PLUGIN_ROOT}/templates/backlog.md there.
    • If git check-ignore -q factory/jobs/x fails, append /factory/jobs/ to .gitignore and tell the user to commit it.
    • If git rev-parse --verify <base> fails, stop and tell the user to set Base branch: in AGENTS.md.
    • With Delivery: pr: if gh auth status fails, stop and tell the user to run gh auth login.
  2. Create the job. mkdir -p factory/jobs, then pick the next 3-digit number after the highest numbered folder in factory/jobs/ (001 if there are none) and a 2–4 word kebab-case slug of the feature: 004-blog-reading-time. Claim it with mkdir factory/jobs/<job-id> (no -p). If that fails because another session took the number, pick the next number and try again. The worktree path is $(cd .. && pwd)/$(basename "$PWD")-factory/<job-id>, run from <repo>. Write job.json with that worktree, stage: "spec", round: 0 and all reviews pending.
  3. Worktree. Create the branch and its worktree from <base>:
    git worktree add -b factory/<job-id> <worktree> <base>
    Then, in the worktree, run the setup AGENTS.md gives for a fresh checkout (installing dependencies, for example), plus the per-job setup from its ## Factory section if it has one. If any of it fails, stop and tell the user.
  4. Spec. Spawn software-factory:spec-writer with the prompt <paths> Feature: <feature, verbatim>. Wait for it to finish, then check that spec.md exists.
  5. Build. Set stage: "build". Spawn software-factory:builder with the name builder-<job-id> and the prompt <paths> Build round 1. Port: <port>. Wait for it to finish, then go to Build check.

Build check

Read the first line of build.md.

  • STATUS: READY: start the next review round.
  • STATUS: BLOCKED: go to Developer review.

Review round N

  1. Set stage: "review", round: N and all four reviews to pending. Create factory/jobs/<job-id>/round-<N>/.
  2. UI check. Run git diff --name-only <base>...factory/<job-id> in the worktree. The branch touches the UI when any file matches the UI paths: line in the ## Factory section of AGENTS.md, or, without that line, when any file is a page, component, style, template or translation file (.vue, .tsx, .jsx, .svelte, .html, .css, .scss, or a path containing locales/ or i18n/). If it doesn't, skip reviewer-ux and reviewer-ui this round: write review-ux.md and review-ui.md in round-<N>/ yourself, each reading VERDICT: PASS, a blank line, and Skipped: no UI files in the diff., and set both to PASS in job.json. Check again every round, since a fix can touch the UI.
  3. Spawn the reviewers that weren't skipped in one message, so they run in parallel. Each gets the prompt <paths> Review round N., plus its port for reviewer-ux and reviewer-ui.
  4. WAIT FOR ALL. Each time a reviewer finishes, read the first line of its file (VERDICT: PASS or VERDICT: CHANGES) and write that verdict to job.json straight away, so the dashboard chips fill in as they land. The round is done only when all four review-*.md files exist in round-<N>/. Never resume the builder mid-round. If a reviewer finishes without writing its file, or writes a first line that isn't a verdict, stop and tell the user.
  5. Decide:
    • All PASS: go to Approve.
    • Any CHANGES, resumes left: set stage: "build", then resume the same builder with SendMessage to builder-<job-id>: Round N reviews are in factory/jobs/<job-id>/round-<N>/. Address every review with VERDICT: CHANGES, commit, and update build.md for round N+1. Wait for it to finish, then go to Build check.
    • Any CHANGES, no resumes left: write decision.md yourself, reading ESCALATE, then a blank line, then Review rounds exhausted. Outstanding CHANGES in round-<N>/ from: <reviewers>. Go to Developer review.

Approve

Set stage: "approve". Spawn software-factory:approver with the prompt <paths> Final round: N. When it finishes, check that the first line of decision.md is APPROVE or ESCALATE (otherwise stop and tell the user), then go to Developer review. Either way the developer decides; ESCALATE only tells them to look harder.

Developer review

Set stage: "dev-review", decision and head (see job.json). The branch, its worktree and the per-job setup stay as they are, so the developer can read the diff, run the app and commit fixes in the worktree. Tell the user:

  • which job is waiting and why: the approver's recommendation, the BLOCKED reason from build.md, or what failed in Deliver;
  • the ## For the human section of decision.md, quoted;
  • under the heading See the changes in your IDE, a bash code block with code <worktree> (the worktree folder, not a single file), then a second bash block with git -C <worktree> diff --stat <base>...factory/<job-id> listing the changed files to open there;
  • the next step: /factory approve <job-id> to deliver, /factory rework <job-id> <note> to send it back, or commit in the worktree first and then approve.

Deliver

With Delivery: pr go to Pull request, otherwise to Merge.

Pull request

Nothing here touches the main checkout. In the worktree:

  1. Run the per-job teardown from the ## Factory section of AGENTS.md, if there is one (a failing teardown doesn't block the PR; tell the user). Then list the developer's own commits: git log --format='%h %s' <head>..factory/<job-id>, with <head> from job.json.
  2. git push -u origin factory/<job-id>.
  3. Write factory/jobs/<job-id>/pr.md as the PR body: the feature in one or two sentences, Fixes <issue key> on its own line when the job has an issue (so Linear links and closes it), the summary from build.md, one line per review round with the four verdicts, the first paragraph of decision.md, the line Reviewed and approved by <git config user.name> via /factory approve., and, if there are any, the developer's own commits under Changes by the developer. If the repo has .github/pull_request_template.md, follow its headings.
  4. gh pr create --base <base> --head factory/<job-id> --title "<title>" --body-file <repo>/factory/jobs/<job-id>/pr.md, where <title> is the feature as a short imperative sentence, prefixed with <issue key>: when there is an issue.

Write the PR URL that gh prints to job.json as pr and set stage: "pr-open". Then git worktree remove <worktree> and git branch -D factory/<job-id> (the branch lives on in the remote). If the push or gh pr create fails, keep the worktree and go to Developer review with what failed. Never push to <base>, never merge the PR, never force-push.

Merge

The merge happens in the main checkout, so it must be clean and on <base>: git status --porcelain -- . ':!factory/backlog.md' prints nothing and git branch --show-current prints <base>. factory/backlog.md is exempt: every /factory next edits it, and job branches never touch it, so a dirty backlog cannot conflict with the merge. If not, the job stays in dev-review: tell the user the main checkout is busy and to run /factory approve <job-id> again once it is clean. Otherwise, first run the per-job teardown from the ## Factory section of AGENTS.md in the worktree, if there is one (a failing teardown doesn't block the merge; tell the user). Then:

git merge --no-ff factory/<job-id> -m "Merge factory/<job-id>" -m "Approved by <git config user.name> via /factory approve."
git worktree remove <worktree>
git branch -d factory/<job-id>

Set stage: "merged". If the merge fails, run git merge --abort (when a merge is in progress) and go to Developer review with why it failed. If removing the worktree fails, the job is still merged: tell the user what git worktree remove printed. Never push.

/factory next

With Task source: linear, take the next issue as described in Linear. Otherwise read factory/backlog.md and take the first - [ ] item. Claim it with one Edit that replaces its exact line with - [x] <item> → claimed. If the Edit fails because the line changed, another session claimed it: re-read the backlog and try the next - [ ] item. If none is left, say so and stop.

Run /factory <item>, and once step 1 has given it a job id, replace claimed on its backlog line with the job id.

/factory <issue key>

When the argument is a Linear issue key (^[A-Z][A-Z0-9]*-[0-9]+$, for example ABC-123), fetch the issue and claim it (see Linear). Then run /factory <feature> with the issue's title and description as the feature, the slug taken from the title, and issue set in job.json. This works with either task source.

Linear

Needs a Linear MCP server in the session (its tools list, read, update and comment on issues). If none is connected, stop and tell the user to connect one, for example claude mcp add --transport http linear https://mcp.linear.app/mcp. Settings, all optional, as lines in the ## Factory section of AGENTS.md:

  • Linear team: <team key>: which team's issues /factory next looks at. Without it, use the only team the user can see, or ask.
  • Linear label: <label> (default factory): only issues with this label are queued for /factory next.
  • Linear states: <todo>, <in progress>, <in review>, <done> (default Todo, In Progress, In Review, Done): the workflow state names to use.

Next issue. List the team's issues with the label in state <todo> that are unassigned, ordered by priority (urgent first, no priority last), then oldest first. Take the first and claim it. If the claim shows someone else got there first, take the next. If none is left, say so and stop.

Claim. Assign the issue to the user the MCP server acts as and set it to <in progress>. Then fetch it again: if it is assigned to someone else, it was taken. For /factory <issue key>, an issue already assigned to someone else stops the job: tell the user who has it.

Updates. Keep the issue in step with the job, each as one MCP call:

  • Job created: comment Factory job <job-id> started on factory/<job-id>.
  • PR opened: comment with the PR URL, set <in review>.
  • Merged (Delivery: merge): comment Merged into <base>., set <done>.
  • Developer review: comment Waiting for developer review. and the reason (the approver's recommendation, the BLOCKED line from build.md, or what failed). The state stays <in progress>.

A failing Linear call never stops or fails the job: tell the user and go on.

/factory approve <job-id>

The job must be in dev-review. If the last build.md reads STATUS: BLOCKED and the branch has no commits after head, there is nothing to deliver: refuse and point to rework or to committing a fix first. Otherwise run Deliver with that job id. Commits the developer made in the worktree are delivered as they are, without another review round.

/factory rework <job-id> <note>

The job must be in dev-review.

  1. Write the note, verbatim, to factory/jobs/<job-id>/rework-<k>.md, where k is the next unused number.
  2. Set stage: "build".
  3. Spawn a fresh software-factory:builder named builder-<job-id> with the prompt <paths> Rework: read rework-<k>.md and address it, then update build.md for round N+1. Port: <port>. (N is the job's last round.) A rework run gets a fresh MAX_RESUMES.
  4. Continue from Build check, exactly like a new job.

Reporting

Keep the user posted with one short line per transition, for example 003-rate-limiting: round 2, security CHANGES, ux/ui/code PASS → resuming builder. When the loop stops, say that the job waits in dev-review and why; after /factory approve, say whether it merged or opened a PR (with its URL).

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.