Skip to main content

Factory

@bonsai/factory is a nightly human-in-the-loop code factory. It surveys the repository, selects a small set of high-value ideas, implements and verifies each idea in isolation, and opens pull requests for review.

It never merges. Failed verification discards the attempted change and opens no PR for that idea.

Pipeline

ideate -> select -> branch -> implement -> verify -> commit -> push -> PR

The production loop is built from injectable seams:

SeamProduction runnerBacked by
IdeationAgentmakeClaudeIdeationClaude Agent SDK with read-only tools.
ImplementationAgentmakeClaudeImplementationClaude Agent SDK with write tools.
VerifiermakeShellVerifierbunx turbo run typecheck test build by default.
GitShellGitGit CLI.
ForgeGhForgeGitHub CLI.
LedgerFileLedgerJSON at .factory/ledger.json.

The orchestration in src/factory.ts is pure and unit-tested with fakes. Side-effecting implementations live in src/runners/.

Prerequisites

  • Bun workspace dependencies installed.
  • ANTHROPIC_API_KEY for Claude Agent SDK ideation and implementation.
  • Authenticated GitHub CLI (gh) for PR creation.
  • A clean enough working tree for factory branches, commits, pushes, and PRs.

Read-only ideate and plan require the API key but do not need GitHub write access.

Install and Develop

cd apps/factory
bun install
bun run build

Development checks:

bun test
bun run typecheck
bun run build

Commands

factory ideate [options]
factory plan [options]
factory run [options]
factory ledger [--limit n]
factory --version
factory --help

From source:

bun apps/factory/src/cli.ts ideate
bun apps/factory/src/cli.ts plan
bun apps/factory/src/cli.ts run --max 3
bun apps/factory/src/cli.ts ledger

Command behavior:

  • ideate: ask Claude for ranked ideas and print JSON. No code changes.
  • plan: show which ideas would be built after ledger and branch de-duplication. No code changes.
  • run: ideate, select, implement, verify, commit, push, and open PRs.
  • ledger: print recent attempts from the factory ledger.
  • run --dry-run: aliases to plan.

Options and Environment

Flags override FACTORY_* environment variables, which override defaults.

EnvFlagDefaultMeaning
FACTORY_MAX_PRS--max <n>3Maximum PRs to open per run.
FACTORY_IDEA_COUNT--ideas <n>8Ideas to request from ideation. Always at least maxPrs.
FACTORY_BASE_BRANCH--base <branch>mainBranch to cut from and target.
FACTORY_GUIDANCE--guidance <text>unsetExtra steering for ideation.
FACTORY_DRAFT--draftfalseOpen PRs as drafts.
FACTORY_VERIFY_COMMANDnonebunx turbo run typecheck test buildVerification gate command.
FACTORY_LEDGER_PATHnone.factory/ledger.jsonLedger path.
FACTORY_BRANCH_PREFIXnonefactory/Branch prefix.

Claude runner env:

EnvDefaultMeaning
FACTORY_CLAUDE_TOOLSRead,Glob,Grep,Edit,Write,BashTool list for implementation.
FACTORY_CLAUDE_PERMISSION_MODEbypassPermissionsClaude SDK permission mode.

Ledger and De-duplication

The factory avoids repeating work by consulting:

  • Recent ledger entries.
  • Existing branches with the configured factory branch prefix.

Each attempt records status, title, timestamp, optional PR URL, and notes. Use:

factory ledger --limit 20

Scheduling

.github/workflows/factory.yml runs the factory nightly at 07:00 UTC and supports manual dispatch with max, guidance, and dry_run inputs.

Repository secrets:

  • ANTHROPIC_API_KEY is required.
  • FACTORY_GH_TOKEN is optional. Use a PAT if PRs opened by the workflow need to trigger downstream CI; PRs opened by the default GITHUB_TOKEN do not trigger every workflow.

Safety Model

  • plan gives a no-change preview of selected work.
  • run verifies each implementation before opening a PR.
  • Red verification means no PR is opened for that idea.
  • The factory opens reviewable PRs and stops. Humans own review and merge.
  • Verification defaults to the full monorepo gate:
bunx turbo run typecheck test build