- Purpose: Run Codex in a durable, repeatable loop against a target git repo using a living ExecPlan, with logs and audit-friendly commits.
- Primary goals: safety (plan-driven changes), durability (logs + plan state), and repeatability (deterministic scripts).
- Non-goals: providing a general CI system or replacing target-repo tooling.
Assumptions: The system is used locally with Docker installed and a target repository checked out on disk.
- Style: Scripted orchestration with a containerized execution boundary.
- Rationale: Bash scripts are the simplest coordination layer for local workflows, and Docker isolates the Codex runtime from host dependencies.
- Runner:
run-ralph.shorchestrates a loop, mounts the target repo, and launches the container. - Container entrypoint:
afk-ralph.shruns inside the container and invokescodex execwith the plan and schema. - Setup/auth:
authenticate-codex.shanddocker/codex-setup.shbuild the image and install/authenticate the Codex CLI. - Project initialization:
init-project.shseeds.agent/PLANS.mdand.agent/execplans/execplan.mdinto a target repo. - Shared helpers:
scripts/lib.shprovides logging (including optional color), config parsing, path expansion, target repo resolution/validation (includingresolve_project_path), and Docker helpers (includingdocker_compose_checked). - Dependency preflight:
scripts/lib.shexposespreflight_depsto install JS dependencies in the target repo when needed. - Templates/config:
templates/PLANS.md,ralph.config.toml, andralph.schema.jsondefine plan rules, defaults, and output schema.
docker/: container setup scripts and Codex CLI setup.scripts/: shared helper library and preflight tooling.templates/: plan rules template copied into target repos.runs/: per-project logs and structured outputs.- Root scripts:
run-ralph.sh,afk-ralph.sh,init-project.sh,authenticate-codex.sh.
- Host flow: user runs
run-ralph.sh-> readsralph.config.toml-> validates Docker -> starts container. - Container flow:
afk-ralph.sh->codex exec-> edits target repo mounted at/work-> writes logs and JSON output. - Host-to-container handoff:
run-ralph.shis the only host entrypoint; it launches theralphcontainer with the fullRALPH_*environment.afk-ralph.shruns only inside the container. - Boundary: the target repo is mounted read/write; all code changes occur there, never in this runner repo.
- Logging: standardized
log_info,log_warn,log_error,log_step, andlog_successinscripts/lib.sh, with optional ANSI color enabled viaRALPH_LOG_COLOR=1when stdout is a TTY. - Error handling:
set -euo pipefailin scripts; fail fast on missing requirements via sharedrequire_filehelper (supports optional hints), and on invalid argument counts via inline checks in helpers likepreflight_deps. - Configuration:
ralph.config.tomlread viaread_config_value(includingmodel_reasoning_effort); path expansion handled insideresolve_project_path; target repo resolution viaresolve_project_path. - Caching: per-run caches under
runs/<project>/.ralph/to reduce repeated installs.
- Docker and Docker Compose v2 for runtime isolation.
- Codex CLI installed via npm inside the container.
- Git required in the target repo to enforce plan-based changes and commits.
- Optional JS package managers in the target repo: npm, pnpm, yarn.
- Execution is local via
docker compose; no remote deploy target. - Environment variables passed into the container define plan paths, log paths, and run directories.
- The host filesystem is mounted into the container at
/workfor the target repo and at/workspacefor the runner repo.
- Use Docker to keep Codex tooling isolated from host dependencies and ensure repeatability.
- Treat
.agent/execplans/execplan.mdin the target repo as the single source of truth for work. - Centralize shared helpers in
scripts/lib.shto remove duplicate logic and keep behavior consistent. - Keep logging helpers centralized and opt into color only for the long-running loop via
RALPH_LOG_COLOR. - Resolve and validate target repo paths through a single shared helper to prevent drift across host entrypoints.
- Centralize project path resolution in
resolve_project_pathto keep host entrypoints consistent. - Centralize Docker Compose preflight via
docker_compose_checked, passing explicit subcommands likerun --rmorbuildto keep entrypoints consistent.
flowchart LR
User --> Runner[run-ralph.sh]
Runner --> Docker[Docker Compose]
Docker --> Container[afk-ralph.sh]
Container --> Codex[codex exec]
Codex --> TargetRepo[/Target Repo/]
Container --> Logs[/runs/<project>/.ralph/]
- Reintroducing duplicate helper functions outside
scripts/lib.sh. - Modifying a target repo without a plan in
.agent/execplans/execplan.md. - Writing runner logs into the target repo.
- Should the runner support a non-Docker execution path for environments where Docker is unavailable?