cpdeol

Tooling

Factory

The factory is a queue-driven automation system that runs repeatable work in clean git worktrees, verifies results, and merges successful changes into main.

How to use

Observe runs and queue state in the checked-in files under agents/ (for example factory-queue.json and factory-runs.json).

Run one iteration locally with pnpm factory:run-once.

Run continuously with pnpm factory:loop, or run parallel workers with FACTORY_WORKERS=5 pnpm factory:swarm.

How it works

A worker claims one queued item, runs it in an isolated worktree, gates on tsc · lint · build, and only then merges. The issue swarm watches incidents in parallel and feeds auto-heal items back into the same queue.

Factory workerIssue swarmQueued itemClaim itemfile-locked queueWorktree + installfrozen lockfileRun spec.commandbash -lc×Gates pass?tsc · lint · buildCommit + pushMerge to maindirect or PRPost-merge UAToptional · prod smokeDoneyesMark failedFailednoIncident writtenWatch incidentsagents/factory-logsClassify + cooldowncircuit breakerEnqueue auto-healcapped, prioritizednew queue item

Tools registry

Every tool under scripts/agent-factory/ must be documented here.

factory-loop

Factory loop

Continuously runs `factory:reclaim`, `factory:evaluate-goal`, then (when queued count is below `FACTORY_QUEUE_LOW_WATERMARK`, default 20) `factory:research-once` (OpenAI-compatible goal LLM + optional hook + optional calc/weather code signals), `factory:backlog:intake`, and `factory:plan-next`. Every iteration ends with `factory:run-once` (stops the loop on non-zero exit). Optional `FACTORY_AUTONOMOUS_STALL_LOOPS` exits when the goal is `met`, the queue is empty, and research repeatedly adds nothing.

How to use

  • Use when you want one worker running continuously.
  • Stops if `factory:run-once` returns non-zero.
  • Without API keys: tries local Ollama (`FACTORY_RESEARCH_OLLAMA_URL`, default `http://127.0.0.1:11434`; disable probe with `FACTORY_RESEARCH_TRY_OLLAMA=0`), then syncs `factory-goal-spec.json` `roadmap_items` into backlog intake (`FACTORY_RESEARCH_GOAL_SPEC_FALLBACK=0` to disable). With keys: set `FACTORY_RESEARCH_API_KEY` or `OPENAI_API_KEY`, optional `FACTORY_RESEARCH_OPENAI_BASE` + `FACTORY_RESEARCH_MODEL`. Set `FACTORY_RESEARCH_HOOK` for a bash snippet before built-in research.

Commands

  • pnpm factory:loop
  • FACTORY_RESEARCH_PIPELINE=0 pnpm factory:loop

Related files

  • scripts/agent-factory/factory-loop.ts
  • scripts/agent-factory/factory-research-once.ts
  • scripts/agent-factory/factory-research-calc-weather-once.ts
  • scripts/agent-factory/factory-backlog-intake.ts
  • scripts/agent-factory/factory-plan-next.ts
  • scripts/agent-factory/factory-run-once.ts

factory-swarm

Factory swarm

Runs multiple worker loops in parallel for higher throughput, and periodically runs `factory:roadmap:refresh` (market scan → candidates → product select → roadmap generate).

How to use

  • Set `FACTORY_WORKERS` to control worker count.
  • Market refresh: `FACTORY_MARKET_REFRESH_INTERVAL_MS` (default 3600000 = 1h; set 0 to disable).
  • First market run delay: `FACTORY_MARKET_REFRESH_STAGGER_MS` (default 10000).

Commands

  • FACTORY_WORKERS=5 pnpm factory:swarm

Related files

  • scripts/agent-factory/factory-swarm.ts
  • scripts/agent-factory/factory-loop.ts
  • scripts/agent-factory/factory-roadmap-refresh.ts

factory-preflight

Factory worker preflight

Validates git `origin`, merge-strategy env (`FACTORY_MERGE_STRATEGY`, `FACTORY_MONEY_MOVING_PROD`), GitHub CLI auth when PR mode, and deploy URL env when `FACTORY_POST_MERGE_UAT=1` — before `factory:run-once` claims work. The same checks run automatically at the start of each `factory:run-once` (skip with `FACTORY_SKIP_PREFLIGHT=1` for local debugging only).

How to use

  • Run in CI or on a worker host before starting `factory:loop` or scheduled `factory:run-once`.
  • Read `docs/GOVERNANCE.md` for merge vs PR vs money-moving defaults.

Commands

  • pnpm factory:preflight

Related files

  • scripts/agent-factory/factory-preflight.ts
  • lib/agent-factory/factory-preflight.ts
  • docs/GOVERNANCE.md

factory-run-once

Run one factory item

Preflight (git origin, optional `gh`, optional deploy URL for post-merge UAT), then claims one queued item, runs its `spec.command` in a clean worktree (or on `main` when `FACTORY_IMPLEMENT_ON_MAIN=1`), runs `pnpm verify` (same bar as human pre-merge: tsc, lint, audit, build, e2e smoke, e2e:goal-smoke, e2e:proof), optional `spec.acceptance` shell checks, optional `spec.require_diff`, then commits/pushes/merges when there are changes.

How to use

  • Use for debugging a single iteration.
  • Use with a single queued item when you want one pass then exit.
  • Per-item checks: set `spec.acceptance` to a command or string array; set `spec.require_diff: true` to fail no-op commands.
  • Meaningful diffs: stock `pnpm -s factory:implement <id>` must touch roots under `app/`, `components/`, `lib/`, `config/`, `scripts/`, `e2e/`, or `public/`; `.gitignore`-only diffs fail. Disable with `FACTORY_REQUIRE_MEANINGFUL_PATHS=0`; extend with `FACTORY_MEANINGFUL_PATH_PREFIXES`. See `docs/GOVERNANCE.md` and factory env for install retries and reclaim.
  • Commit on current `main` (no agent worktree): `pnpm factory:run-once:main` or `FACTORY_IMPLEMENT_ON_MAIN=1 pnpm factory:run-once`. Requires cwd at repo root, checkout on `main`, clean tree, `FACTORY_MERGE_STRATEGY=direct`, merge `origin/main` before implement. Optional `FACTORY_IMPLEMENT_ON_MAIN_INSTALL=1` runs `pnpm install` in the root.
  • Cursor-only implement: `pnpm factory:run-once:cursor` or `FACTORY_IMPLEMENT_BACKEND=cursor` (see `agents/factory-goal-spec.json` and optional goal prose in `agents/`).
  • Default `pnpm -s factory:implement <id>` runs `pnpm` directly (no shell). Other `spec.command` values and acceptance checks use `bash -c` (inherits `PATH`). Set `FACTORY_BASH_LOGIN=1` for `bash -lc` if nvm needs a login profile.

Commands

  • pnpm factory:run-once
  • pnpm factory:run-once:main
  • FACTORY_IMPLEMENT_ON_MAIN=1 pnpm factory:run-once
  • pnpm factory:run-once:cursor
  • FACTORY_IMPLEMENT_BACKEND=cursor pnpm factory:run-once

Related files

  • scripts/agent-factory/factory-run-once.ts
  • lib/agent-factory/factory-preflight.ts
  • lib/agent-factory/item-spec.ts
  • lib/agent-factory/require-diff-guards.ts
  • docs/GOVERNANCE.md
  • agents/factory-queue.json
  • agents/factory-runs.json

factory-plan-next

Planner: enqueue next work

Refills the queue from the roadmap. If the roadmap file has **zero** rows, runs market research refresh (scan → score → select → generate roadmap) then retries. If every roadmap id is already on the queue (non-cancelled), it does **not** refresh the roadmap. With `FACTORY_GOAL_STATE_CONTROLS_PLAN=1`, skips enqueue when `agents/factory-goal-state.json` status is `met`.

How to use

  • Use when the queue is low and you want the factory to enqueue next work.

Commands

  • pnpm factory:plan-next
  • FACTORY_GOAL_STATE_CONTROLS_PLAN=1 pnpm factory:plan-next

Related files

  • scripts/agent-factory/factory-plan-next.ts
  • agents/factory-roadmap.json
  • agents/factory-queue.json
  • agents/factory-goal-state.json
  • scripts/agent-factory/factory-roadmap-refresh.ts

factory-plan-from-goal

Planner: merge goal spec into roadmap

Reads `agents/factory-goal-spec.json` (`statement`, `roadmap_items`) and upserts those rows into `agents/factory-roadmap.json`, then bumps roadmap meta seq. Use after you (or another agent) decompose a goal into concrete roadmap rows.

How to use

  • Edit `agents/factory-goal-spec.json` with `roadmap_items` (id, title, priority, optional `traces_goal` and/or `spec` with first `definition_of_done` bullet tracing the `statement`).
  • Run `pnpm factory:plan-from-goal`, then `pnpm factory:plan-next` to enqueue.

Commands

  • pnpm factory:plan-from-goal

Related files

  • scripts/agent-factory/factory-plan-from-goal.ts
  • agents/factory-goal-spec.json
  • agents/factory-roadmap.json

factory-research-once

Research: goal LLM + optional hook + calc/weather signals

Runs autonomous research for the current `factory-goal-spec.json`: builds the LLM prompt from goal state (`agents/factory-goal-state.json` summary + per-item queue status when present), roadmap rows, optional deterministic calculator/weather **repo signal** hints, and existing ids. Uses **remediation** instructions when state is `blocked` or `queue_failed` > 0 (disable with `FACTORY_RESEARCH_REMEDIATION_PROMPT=0`), **improvement** when status is `met` and `FACTORY_RESEARCH_IMPROVEMENT_WHEN_MET` is on, otherwise milestone planning. Calls an OpenAI-compatible API when keys are set; runs optional `FACTORY_RESEARCH_HOOK`, then optional calc/weather backlog append. Writes `agents/factory-research-last.json` including `research_prompt_mode` and `appended_total`.

How to use

  • No keys: Ollama auto-detect + goal-spec `roadmap_items` → backlog intake. With keys: `FACTORY_RESEARCH_API_KEY` or `OPENAI_API_KEY`; optional `FACTORY_RESEARCH_MODEL` and `FACTORY_RESEARCH_OPENAI_BASE` (e.g. Groq).
  • Use `FACTORY_RESEARCH_HOOK` for a custom bash snippet that edits `backlog.md` before the built-in steps.

Commands

  • pnpm factory:research-once

Related files

  • scripts/agent-factory/factory-research-once.ts
  • lib/agent-factory/run-goal-llm-research-append.ts
  • lib/agent-factory/research-goal-context.ts
  • lib/agent-factory/research-goal-llm.ts
  • lib/agent-factory/run-calc-weather-research-append.ts
  • agents/factory-goal-state.json
  • agents/factory-research-last.json

factory-research-calc-weather-once

Research: calculator / weather code signals only

Runs deterministic scan of `app/calculator/page.tsx`, optional calculator layout, weather page, and weather API sources; appends suggested backlog intake rows to `backlog.md` when signals match (e.g. missing route metadata, keyboard a11y). Does not call an LLM — use after `factory:research-once` when you want calc/weather hints only.

How to use

  • Run `pnpm factory:research:calc-weather-once` from repo root; then `pnpm factory:backlog:intake` and `pnpm factory:plan-next` if new rows were appended.
  • Forced from research pipeline when `FACTORY_RESEARCH_CALC_WEATHER=force`; skipped when set to `0`.

Commands

  • pnpm factory:research:calc-weather-once

Related files

  • scripts/agent-factory/factory-research-calc-weather-once.ts
  • lib/agent-factory/run-calc-weather-research-append.ts
  • lib/agent-factory/research-calc-weather-signals.ts
  • backlog.md

factory-backlog-intake

Planner: merge research backlog into roadmap

Parses the `## Factory research intake` section in `backlog.md` (research agent output) and upserts those rows into `agents/factory-roadmap.json` with default `factory:implement` commands, then bumps roadmap meta seq. Run before `factory:plan-next` so the factory queue can pick up new work.

How to use

  • Research agent appends tasks under `## Factory research intake` using the `### ID — title` / `- Priority:` / optional `- Command:` shape.
  • Run `pnpm factory:backlog:intake`, then `pnpm factory:plan-next` (or rely on `factory:loop` after intake).

Commands

  • pnpm factory:backlog:intake

Related files

  • scripts/agent-factory/factory-backlog-intake.ts
  • lib/agent-factory/backlog-intake.ts
  • backlog.md
  • agents/factory-roadmap.json

factory-evaluate-goal

Goal-level evaluation

Writes `agents/factory-goal-state.json`: compares roadmap ids to queue statuses, runs optional `goal_acceptance` shell checks from `factory-goal-spec.json` when every linked item is done, sets status to `met`, `active`, `blocked`, or `unknown`. Summary and optional `roadmap_not_done` list id+title+queue_status for rows not done. Invoked automatically each `factory:loop` iteration after reclaim.

How to use

  • Set `goal_acceptance` when you have a repo-level check that proves the overall outcome.
  • Use `FACTORY_GOAL_STATE_CONTROLS_PLAN=1` with `factory:plan-next` to stop enqueueing when status is `met`.
  • Stdout lists each roadmap row not done (id, title, queue/missing); `agents/factory-goal-state.json` may include `roadmap_not_done` for the same.

Commands

  • pnpm factory:evaluate-goal

Related files

  • scripts/agent-factory/factory-evaluate-goal.ts
  • lib/agent-factory/goal-spec.ts
  • agents/factory-goal-spec.json
  • agents/factory-goal-state.json

factory-goal-pivot

Goal pivot (cancel stale queue work)

After you change the north star in `agents/factory-goal-spec.json`, run this to align the factory: first run initializes `agents/factory-goal-meta.json` and stamps `goal_revision` on active queue rows; later runs cancel queued/in_progress/blocked rows whose `goal_revision` no longer matches the current spec so planning can focus on the updated goal.

How to use

  • Post–goal-change sequence: bump `goal_revision` (or edit `statement` for hash fallback) → `pnpm factory:goal-pivot` → `pnpm factory:plan-from-goal` (or roadmap regen) → `pnpm factory:plan-next`.
  • Pivot events append to `agents/factory-pivot-log.jsonl` (gitignored).

Commands

  • pnpm factory:goal-pivot

Related files

  • scripts/agent-factory/factory-goal-pivot.ts
  • lib/agent-factory/goal-io.ts
  • lib/agent-factory/goal-spec.ts
  • agents/factory-goal-spec.json
  • agents/factory-goal-meta.json
  • agents/factory-queue.json

factory-reclaim

Reclaim stale claims/runs

Repairs the queue/runs ledger after crashes by reclaiming stale work and keeping the dashboard consistent.

How to use

  • Use when a worker crashed and items look stuck in `in_progress`.
  • `FACTORY_STALE_CLAIM_MS` / `FACTORY_STALE_RUN_MS` — see `docs/GOVERNANCE.md` (factory env / script defaults).

Commands

  • pnpm factory:reclaim

Related files

  • scripts/agent-factory/factory-reclaim.ts
  • lib/agent-factory/reclaim-thresholds.ts
  • agents/factory-queue.json
  • agents/factory-runs.json

factory-doctor

Factory doctor (worker smoke)

Read-only check: Node/pnpm versions, `pnpm-lock.yaml`, effective reclaim thresholds, implementer env hints (`FACTORY_CLAUDE_BIN`, aider/Gemini).

How to use

  • Run on a worker host before starting `factory:loop` or `factory:swarm`.

Commands

  • pnpm factory:doctor

Related files

  • scripts/agent-factory/factory-doctor.ts
  • docs/GOVERNANCE.md

factory-queue-dedupe

Queue dedupe (same title + goal)

Cancels duplicate `queued` rows that share the same title and `goal_revision`, keeping the highest `_V##` suffix in the item id. Dry-run with `FACTORY_QUEUE_DEDUPE_DRY_RUN=1`.

How to use

  • Use after research/intake created many calculator-fix clones (V10…V13).
  • Preview: `FACTORY_QUEUE_DEDUPE_DRY_RUN=1 pnpm factory:queue:dedupe`.

Commands

  • pnpm factory:queue:dedupe
  • FACTORY_QUEUE_DEDUPE_DRY_RUN=1 pnpm factory:queue:dedupe

Related files

  • scripts/agent-factory/factory-queue-dedupe.ts
  • lib/agent-factory/queue-dedupe.ts
  • agents/factory-queue.json

factory-stabilize

Stabilize environment

Restores a missing `tsx` shim if needed, runs `factory:reclaim`, then `factory:maintenance` to clear orphan worktrees and run git maintenance.

How to use

  • Use when `tsx` is missing from `node_modules/.bin` or after worker crashes left the queue in a bad state.

Commands

  • pnpm factory:stabilize

Related files

  • scripts/agent-factory/factory-stabilize.ts
  • scripts/agent-factory/factory-reclaim.ts
  • scripts/agent-factory/factory-maintenance.ts

factory-issue-swarm

Issue swarm

Watches swarm incidents (and optional Vercel deploy errors), enqueues `auto_heal` jobs on `factory-queue.json`, and appends the same work as rows under `## Factory research intake` in `backlog.md` so `factory:backlog:intake` can promote them to the roadmap. Disable backlog logging with `FACTORY_ISSUE_SWARM_LOG_BACKLOG_INTAKE=0`.

How to use

  • Use when you want the factory to watch for incidents and enqueue maintenance tasks automatically.
  • After swarm logging, run `pnpm factory:backlog:intake` if roadmap should mirror those heal IDs.

Commands

  • pnpm factory:issue-swarm
  • FACTORY_ISSUE_SWARM_LOG_BACKLOG_INTAKE=0 pnpm factory:issue-swarm

Related files

  • scripts/agent-factory/factory-issue-swarm.ts
  • agents/factory-logs/swarm-incidents/
  • backlog.md
  • lib/agent-factory/backlog-intake.ts

factory-maintenance

Maintenance runner

Applies remediations for a specific incident file produced by the swarm.

How to use

  • Use to remediate a specific incident JSON from `agents/factory-logs/swarm-incidents/`.

Commands

  • pnpm factory:maintenance "agents/factory-logs/swarm-incidents/<incident>.json"

Related files

  • scripts/agent-factory/factory-maintenance.ts
  • agents/factory-logs/swarm-incidents/

factory-learn-github

Learn from merged PR reviews

Pulls high-signal review comments from recently merged PRs into `agents/factory-learnings.json` for later rule/workflow hardening.

How to use

  • Requires GitHub CLI (`gh`) authenticated for the repo.
  • Run on a cadence (weekly) or after major merges.

Commands

  • pnpm factory:learn-github

Related files

  • scripts/agent-factory/factory-learn-github.ts
  • agents/factory-learnings.json

factory-roadmap-expand

Roadmap expander

Turns roadmap items into actionable `backlog.md` entries so the factory can keep shipping incremental planning work.

How to use

  • Use when you want to expand a roadmap item into a structured backlog entry.

Commands

  • pnpm factory:roadmap:expand <ITEM_ID>

Related files

  • scripts/agent-factory/factory-roadmap-expand.ts
  • agents/factory-roadmap.json

factory-market-scan

Market scan

Fetches configured RSS/URL sources and caches citations into `agents/market-evidence.json`.

How to use

  • Tune sources in `agents/market-sources.json`.
  • Optional: `FACTORY_MARKET_FETCH_TIMEOUT_MS`, `FACTORY_MARKET_FETCH_DELAY_MS`.

Commands

  • pnpm factory:market:scan

Related files

  • scripts/agent-factory/factory-market-scan.ts
  • agents/market-sources.json
  • agents/market-evidence.json

factory-candidates-refresh

Product candidates refresh

Scores product seeds against evidence and writes `agents/product-candidates.json`.

How to use

  • Edit seeds in `agents/product-seeds.json`.
  • Requires `agents/market-evidence.json` (or starts empty).

Commands

  • pnpm factory:candidates:refresh

Related files

  • scripts/agent-factory/factory-candidates-refresh.ts
  • agents/product-seeds.json
  • agents/product-candidates.json
  • lib/agent-factory/market.ts

factory-product-select

Product selection

Picks the top scored candidate and writes `agents/selected-product.json`.

How to use

  • Run after `pnpm factory:candidates:refresh`.

Commands

  • pnpm factory:product:select

Related files

  • scripts/agent-factory/factory-product-select.ts
  • agents/selected-product.json

factory-roadmap-generate

Roadmap generator

Builds `agents/factory-roadmap.json` from `agents/selected-product.json` using a revenue-loop-first template.

How to use

  • Run after `pnpm factory:product:select`.

Commands

  • pnpm factory:roadmap:generate

Related files

  • scripts/agent-factory/factory-roadmap-generate.ts
  • agents/selected-product.json
  • agents/factory-roadmap.json
  • agents/factory-roadmap-meta.json

factory-roadmap-refresh

Roadmap refresh pipeline

Runs market scan → candidates → product select → roadmap generate (best-effort per step).

How to use

  • Normally invoked by `pnpm factory:plan-next` when the roadmap is exhausted.

Commands

  • pnpm factory:roadmap:refresh

Related files

  • scripts/agent-factory/factory-roadmap-refresh.ts

factory-implement

Developer agent: implement roadmap item

Builds a prompt from ``agents/factory-goal-spec.json` and optional goal prose in repo`, the roadmap row DoD, and `agents/SKILL-developer.md`, then spawns the configured implementer (default `claude` via stdin for `-p` mode) in the current worktree — unless `FACTORY_IMPLEMENT_BACKEND` is `cursor`, `none`, or `skip`, in which case it only writes `agents/factory-logs/cursor-task-<ID>.md` for Cursor/manual work. Does not install, build, or commit; `factory:run-once` runs `pnpm verify` afterward (including `e2e:goal-smoke` for goal-truth UI/API checks per `agents/factory-goal-spec.json`).

How to use

  • Typically invoked as `pnpm -s factory:implement <ITEM_ID>` from a queue item `spec.command`.
  • Set `FACTORY_ROOT` when the worktree cwd is not the repo root.
  • Cursor-only: `pnpm factory:implement:cursor -- <ITEM_ID>` or `FACTORY_IMPLEMENT_BACKEND=cursor pnpm -s factory:implement <ITEM_ID>` (see ``agents/factory-goal-spec.json` and optional goal prose in repo`).

Commands

  • pnpm -s factory:implement FACTORY_VERIFY_CALCULATOR_V1
  • pnpm factory:implement:cursor -- FACTORY_VERIFY_CALCULATOR_V1
  • FACTORY_IMPLEMENT_BACKEND=cursor pnpm -s factory:implement FACTORY_VERIFY_CALCULATOR_V1

Related files

  • scripts/agent-factory/factory-implement.ts
  • agents/factory-roadmap.json
  • `agents/factory-goal-spec.json` and optional goal prose in repo
  • e2e/goal-smoke.spec.ts

factory-status

Factory status

Prints a concise snapshot of queue health, recent runs, optional worker heartbeats, and log paths for operators debugging the factory loop.

How to use

  • Run `pnpm factory:status` on the repo root or worker host.

Commands

  • pnpm factory:status

Related files

  • scripts/agent-factory/factory-status.ts
  • agents/factory-queue.json
  • agents/factory-runs.json
  • agents/factory-logs/

claude-ollama-wrapper

Ollama adapter for factory-implement

Shell wrapper that translates `claude` CLI stdin/stdout protocol to Ollama API calls. Allows `factory:implement` to use local Ollama (e.g., llama3.2) instead of Claude API when `FACTORY_CLAUDE_BIN` points to this script.

How to use

  • Set `FACTORY_CLAUDE_BIN='./scripts/agent-factory/claude-ollama-wrapper.sh'` before running `factory:run-once`.
  • Reads prompt from stdin, sends to Ollama API (default `http://127.0.0.1:11434`; override with `FACTORY_RESEARCH_OLLAMA_URL`).
  • Uses `FACTORY_RESEARCH_MODEL` (default `llama3.2`) as the Ollama model.

Commands

  • FACTORY_CLAUDE_BIN='./scripts/agent-factory/claude-ollama-wrapper.sh' pnpm factory:run-once

Related files

  • scripts/agent-factory/claude-ollama-wrapper.sh
  • scripts/agent-factory/factory-implement.ts
  • docs/GOVERNANCE.md