Skip to content

goga build

Execute a build plan via ralphex inside a Docker container.

Synopsis

goga build PLAN [OPTIONS]

Description

goga build launches the goga build pipeline for a given plan file. It prepares the environment, validates preconditions, and delegates execution to ralphex running inside a Docker container with the goga in-container process as the entry point.

The build pipeline performs these steps:

  1. Docker check -- Verifies Docker is installed and accessible.
  2. Config loading -- Reads .goga/config.yml for build settings.
  3. Uncommitted manifest check -- Scans git status for uncommitted CODEMANIFEST files (can be skipped).
  4. Agent preconditions -- Sets up agent-specific files (e.g., .claude/settings.json, .ralphex/claude-wrapper.sh for Claude).
  5. Defaults copy -- Copies default prompts and agent configurations to .ralphex/.
  6. Image refresh (optional) -- When --update/-u is set, the image is refreshed: if a top-level dockerfile is declared in .goga/config.yml, docker build runs against it (build failure is fatal — exit 1); otherwise docker pull runs (a pull failure is logged as a warning and the build proceeds with the locally available image). By default no refresh happens and the local image is used as-is.
  7. Docker execution -- Launches the ralphex command inside the configured Docker image. Credential files for claude, codex, and opencode are detected on the host and bind-mounted read-only into the container automatically (no flag).

Arguments

Argument Description
PLAN Path to the build plan file (required).

Options

Option Type Default Description
--dry-run flag off Print the assembled command without executing
--worktree flag off Enable ralphex worktree mode
--skip-finalize flag off Skip finalization step
--skip-manifest-check flag off Skip check for uncommitted CODEMANIFEST files
--session-timeout string config Session timeout duration
--idle-timeout string config Idle timeout duration
--wait string config Wait time before starting
--max-iterations int config Maximum number of build iterations
--review-patience int config Review patience count
-e, --env string -- Additional environment variable (KEY=VALUE, repeatable)
--proxy string config HTTP/HTTPS proxy URL; overrides build.proxy. Adds HTTP_PROXY/HTTPS_PROXY/NO_PROXY=localhost,127.0.0.1 to the container env-file
--add-host string (repeatable) -- Add a docker run --add-host HOST:IP entry; merges on top of build.hosts (CLI wins on key conflict)
--update, -u flag off Refresh the image before launch (build if a project Dockerfile is declared, else pull). Default skips the refresh
-c, --clean flag off Wipe the persistent ralphex runtime host directory before launch (default preserves state across runs)

Timeout and iteration options fall back to values in .goga/config.yml when not provided on the command line.

Proxy and hosts

--proxy URL (and build.proxy in .goga/config.yml) route the container's traffic through a corporate proxy. When a proxy is resolved, three variables are written to the container env-file:

Variable Value
HTTP_PROXY the resolved proxy URL
HTTPS_PROXY the resolved proxy URL
NO_PROXY localhost,127.0.0.1 (fixed; cannot be overridden)

--add-host HOST:IP (and build.hosts in .goga/config.yml) translate to docker run --add-host HOST:IP flags. CLI entries are merged on top of config; on host-key conflict, the CLI entry wins. Format is split on the first colon only — Docker reports malformed entries itself.

Credential mounts

Credential files for the supported AI agents are detected on the host and bind-mounted read-only into the container automatically (no flag): claude (~/.claude/.credentials.json), codex (~/.codex/auth.json), and opencode (~/.local/share/opencode/auth.json). Detection is agent-agnostic — it is not filtered by the configured task_executor.agent — and only files that exist are mounted. When none exist, no credential mount is added.

Ralphex runtime isolation

ralphex writes its persistent state to a .ralphex/ directory it auto-detects in its working directory. Rather than letting that state accumulate inside your project directory, goga build bind-mounts a centralized host directory over /workspace/.ralphex, so the bytes physically land on the host under:

~/.goga/runtime/builds/<normalized_project>/<branch>/

<normalized_project> is the project's absolute path with leading slashes stripped and remaining slashes replaced by hyphens; <branch> is the current git branch (slashes replaced with hyphens), or default when git is unavailable, the directory is not a repository, or HEAD is detached.

The directory survives across runs of the same project on the same branch by default, so an interrupted build can be resumed. Pass --clean to wipe and recreate it before launch for a fresh run. The host path never reaches the container except as the /workspace/.ralphex mount source — the container sees only /workspace/.ralphex.

Note: concurrent builds of the same project on the same branch share one runtime directory; run them on different branches or use --clean if isolation is required.

Examples

Run a build plan:

goga build plan.md

Dry run to see the command without executing:

goga build plan.md --dry-run

Run with custom timeouts and an extra environment variable:

goga build plan.md --session-timeout 3600 --max-iterations 50 -e ANTHROPIC_API_KEY=sk-xxx

Skip the uncommitted CODEMANIFEST check:

goga build plan.md --skip-manifest-check

Pull the latest image, then build (default skips the pull):

goga build plan.md --update

Route container traffic through a corporate proxy and add a local host entry:

goga build plan.md --proxy http://corp:3128 --add-host foo.local:127.0.0.1

Wipe persistent ralphex state before launching a fresh build:

goga build plan.md --clean

Configuration

Build settings are loaded from .goga/config.yml. Example configuration:

language: python
image: qarium/goga-python-3.12:1.1
# dockerfile: .goga/Dockerfile   # optional — when set, `--update` builds the image from this Dockerfile instead of pulling
pipeline:
  agent: claude
build:
  task_executor:
    agent: claude
    env: {}
  proxy: http://corp:3128      # optional HTTP/HTTPS proxy URL for the build container
  hosts:                        # optional docker run --add-host entries
    foo.local: 127.0.0.1

Only language is required by the loader. goga build additionally requires a build section (it exits with a ClickException when build is absent), a non-None build.task_executor.agent (optional at the loader level — absent/empty/whitespace resolves to None; the command raises a ClickException when it is None, since the build needs an agent to resolve the in-container wrapper), and the top-level image field must be set; otherwise the command exits with an error. The deprecated build.image field is rejected — use the top-level image field. The optional top-level dockerfile field (when set) makes --update build the image locally from that Dockerfile instead of pulling it. The optional build.proxy and build.hosts fields are overridden/augmented by the --proxy and --add-host CLI options respectively.

Exit Codes

Code Meaning
0 Build completed successfully
1 Build failed (Docker not found, config error, precondition failure, ralphex error, or a fatal docker build under --update)