Skip to content

Latest commit

 

History

History
244 lines (177 loc) · 10.7 KB

QUICKSTART.md

File metadata and controls

244 lines (177 loc) · 10.7 KB

Forge Quickstart

Get Forge running in ~5 minutes.

All commands below assume your current working directory is the repo root (forge/).

Prerequisites

  • Python 3.12+ (python3 --version)
  • Git
  • One LLM provider credential:
    • Amazon Bedrock API key or AWS credentials (default provider), or
    • OpenRouter API key (used by ./run-forever.sh and the benchmark harness)
  • OpenCode on PATH — Forge installs it inside the worker image automatically; only needed on the host for ad-hoc tooling
  • Docker Desktop (required since R9.E) — Forge runs every worker inside a container built from Dockerfile.worker. Build the image once with make worker-image.
  • (Optional) nono — kernel-level sandbox invoked by ./run.sh

Install

git clone https://github.com/sjqtentacles/forge.git
cd forge

python3 -m venv .venv
source .venv/bin/activate
pip install -e 'platform[dev]'

Configure API credentials

Forge defaults to Amazon Bedrock (Claude Sonnet 4.6 for primary/secondary/reasoning, Claude Opus 4.6 for the adversary reviewer).

cp .env.example .env
# Edit .env and uncomment the credentials you want to use.

Credential precedence (first non-empty wins):

  1. BEDROCK_API_KEY — direct Bedrock API key
  2. AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY (+ optional AWS_SESSION_TOKEN, AWS_REGION)
  3. OPENROUTER_API_KEY — OpenRouter provider

./run.sh will also extract AWS credentials from your ~/.aws/credentials profile if they are not in .env. See Launcher scripts for details.

Initialize a new project (optional)

If you want to run Forge on a fresh codebase rather than the bundled defaults:

PYTHONPATH=platform python3 -m forge.cli init --name my-project --out /path/to/output --no-llm

Forge-on-Forge — to dogfood Forge against its own monorepo, select the forge_on_forge profile (forge run --profile forge_on_forge). See docs/PROFILES.md and studio/profiles/forge_on_forge.yaml.

This creates:

  • studio/config.yaml — project configuration (paths, commands, features)
  • studio/models.yaml — model aliases and rates (the only file that names model IDs)
  • studio/agents/ — agent prompt templates
  • .forge/ — runtime data directory

Configure your project

Two files. studio/config.yaml describes the project shape; studio/models.yaml pins which models to use. The split is a hard policy — see docs/MODELS.md.

studio/config.yaml:

project:
  name: "my-project"
  language: "python"
  source_root: "."
  module_name: "myproject"
  epic_prefix: "PROJ"
  layout:
    packages_dir: ""
    test_suffix: "test_*.py"
    source_glob: "*.py"
  commands:
    test: "python3 -m pytest -x -q"
    build: "python3 -m py_compile myproject/__init__.py"
    vet: "python3 -m py_compile myproject/__init__.py"
  docs:
    design: ""
    taskboard: "docs/TASKBOARD.md"
  sandbox:
    extra_allow: []
    extra_read: []

worker_runtime: docker  # only supported value since R9.E

# NOTE: model selection lives in studio/models.yaml -- not here.
# See docs/MODELS.md for the policy.

features:
  best_of_n: true
  adaptive_search: true
  mcp_tools: true

studio/models.yaml (the only place model IDs are allowed):

aliases:
  primary:   "<your-primary-model-id>"
  secondary: "<your-secondary-model-id>"
  reasoning: "<your-reasoning-model-id>"
  embedding: "<your-embedding-model-id>"

rates: {}   # optional; per-model USD/1M-token costs for the dashboard

See docs/MODELS.md for the schema, the provider-routing rules, and the four required aliases. See docs/CONFIG-REFERENCE.md for every key in config.yaml.

Create a taskboard

Forge reads epics from docs/TASKBOARD.md (or wherever project.docs.taskboard points). Note: this is the taskboard format — a per-project backlog your epic prefix keys into. The Forge repo itself also ships docs/TASKBOARD.md documenting internal SWE-bench tracking; the format is the same, the scope is different.

Format:

### PROJ-001: User authentication
**Priority:** P0
**Description:** Add JWT-based user authentication.

### PROJ-002: Forgot-password flow
**Description:** Email reset link + token verification.

Or use inline checkboxes:

- [ ] PROJ-003: Rate-limit login endpoint
- [x] PROJ-004: Add /healthz route   <!-- already done, skipped -->

What to expect (cost and time)

A typical small epic (2-4 subtasks, ~200 lines of code) costs $3-8 in LLM API calls and takes 10-20 minutes. Larger epics (6+ subtasks, cross-package refactors) can cost $15-30 and take 30-60 minutes.

Forge uses Sonnet 4.6 for most work and automatically routes the adversarial reviewer to Opus 4.6 when the blast radius exceeds a configurable threshold. Opus calls are 5x more expensive per token but only fire on high-risk changes.

The dashboard (http://127.0.0.1:8420) shows live cost tracking per epic and per session.

Run Forge

The canonical invocation is:

PYTHONPATH=platform .venv/bin/python3 -m forge.cli run --dashboard

Other common modes:

PYTHONPATH=platform .venv/bin/python3 -m forge.cli run --once --max-tasks 3   # one-shot
PYTHONPATH=platform .venv/bin/python3 -m forge.cli run --profile go-game      # named profile

Dashboard is served at http://127.0.0.1:8420 while the engine is running.

Launcher scripts

Two launchers live at the repo root. They are not interchangeable — they target different providers:

Script Provider Sandbox Mode
./run.sh Amazon Bedrock via AWS profile nono (kernel-level) Single run
./run-forever.sh OpenRouter (OPENROUTER_API_KEY) None Continuous daemon

Notes before using them:

  • run.sh reads ~/.aws/credentials and extracts the profile named by $AWS_PROFILE (defaults to default if unset). To use a non-default profile, set AWS_PROFILE=<your-profile> in your shell or in .env before invoking the script.
  • run.sh requires nono to be installed and on PATH.
  • run-forever.sh calls python3 (system Python) directly. Either keep your venv activated or edit the script to use .venv/bin/python3.

Run the tests

python3 -m pytest platform/tests/ -p no:xdist -o "addopts=" -v

The -p no:xdist -o "addopts=" overrides the parallel defaults from platform/pyproject.toml so test output is deterministic. For a fast parallel run, just use python3 -m pytest platform/tests/.

Real-LLM eval cassettes (optional)

R9.E's cassette-gated end-to-end canary replays both the LLM tape (<scenario>.ndjson) and the OpenCode subprocess tape (<scenario>.opencode.ndjson) so the test runs hermetically with zero paid calls and zero live opencode invocations. To bootstrap or refresh the canary cassettes locally (once, paying real Bedrock cost + spinning up the worker container):

make worker-image
FORGE_EVAL_LIVE=1 scripts/capture_eval_cassette.sh canary

The script refuses to run if either cassette already exists; remove both before recapturing so they always come from the same live run. See docs/eval-runs/R9/README.md for the full record/replay contract and drift-handling rules.

Other CLI commands

PYTHONPATH=platform python3 -m forge.cli status --costs       # status + cost summary
PYTHONPATH=platform python3 -m forge.cli config validate      # YAML + structural check
PYTHONPATH=platform python3 -m forge.cli doctor               # preflight: config, PATH, MCP, SQLite
PYTHONPATH=platform python3 -m forge.cli canary               # replay the frozen canary epics
PYTHONPATH=platform python3 -m forge.cli sleeptime            # sleep-time meta-evolution consolidation

PYTHONPATH=platform python3 -m forge.cli task https://github.com/you/repo \
    --description "Add OAuth login"

Example projects

See examples/ for profile templates — each is a studio/config.yaml + studio/agents/ + design/taskboard that you point at your own project tree. They are not self-contained runnable apps. See examples/README.md for how to pair them with a real project.

  • examples/go-game/ — Go colony-sim profile (expects a Go module rooted at game/)
  • examples/python-api/ — FastAPI profile (expects a Python package rooted at src/)

Troubleshooting

Symptom Likely cause Fix
ModuleNotFoundError: forge PYTHONPATH not set Prefix commands with PYTHONPATH=platform, or activate the editable install (pip install -e 'platform[dev]')
No credentials found / Bedrock auth error Neither .env nor AWS profile is populated Set BEDROCK_API_KEY in .env, or configure an AWS profile that the launcher can read
opencode: command not found OpenCode not on PATH Install from https://github.com/opencode-ai/opencode and ensure which opencode succeeds
nono: command not found run.sh expects nono Install from https://nono.sh, or invoke the CLI directly instead of ./run.sh
Cannot connect to the Docker daemon Docker Desktop isn't running (Forge requires it since R9.E) Start Docker Desktop, then re-run. There is no in-process fallback runtime.
UnsupportedRuntimeError: Forge is Docker-only since R9.E Config still sets worker_runtime: local (or claude_code/auto) Set worker_runtime: docker in studio/config.yaml (or remove the key to pick up the default).
Address already in use (127.0.0.1:8420) Prior Forge run still holds the dashboard port lsof -iTCP:8420 -sTCP:LISTEN then kill <pid>. If you need a different port, invoke forge.engine.main --dashboard --dashboard-port 8421 directly (the forge run subcommand does not currently forward a custom port).
SyntaxError on match / str | None at import Python < 3.12 Install Python 3.12+ and recreate the venv
Worker container exits with code 137 Docker OOM-killed the container Increase Docker Desktop memory limit (Settings > Resources) to at least 4 GB. Run docker system prune -f to reclaim disk space from dangling images and build cache.
No such container / RWLayer unexpectedly nil Docker storage layer under pressure Run docker system prune -a to remove unused images, then docker system df to verify disk is healthy. Restart Docker Desktop if errors persist.
Worker keeps committing compiled binaries (Go) Missing .gitignore in the game repo Add the binary name (e.g. /ironhold) and *.test, *.out to your game's .gitignore.