Architecture
plan command group (plan import <file>, plan ls) seeds and lists plans for the current project — resolved by fingerprint, not by a committed per-repo config. Beyond that there are no other command-level subsystems: no variant/persona selection, no attach/cockpit framing. The client is the read-only view; there's nothing separate to attach to.One binary, two modes
radioactive_ralph --supervisor— the long-lived supervisor. It owns every agent subprocess's pty (creack/pty,internal/agent), holds all work open, serves the discovery socket (internal/ipc), runs the reaper, and owns the one user-level SQLite database (internal/store). Working directory is irrelevant to it.radioactive_ralph(no flag) — a dumb client. It discovers the supervisor, resolves the current directory to a known project (auto-initializing if needed), and renders a read-only Bubble Tea TUI. It refuses to run without a live supervisor.radioactive_ralph --init— explicitly registers or re-registers the current directory as a project.radioactive_ralph service {install,uninstall,status}— manages the supervisor as a per-user OS service on macOS and Linux (launchd/systemd) so it survives logout/reboot/crash.service installinstalls or reloads the definition and starts it immediately. Native Windows SCM install/start is intentionally disabled in v0.22; status and uninstall remain remediation operations for prior development registrations.radioactive_ralph doctor— environment checks (git, provider CLIs, service manager).
The plan command group (plan import <file>, plan ls) seeds and lists
plans for the current project — resolved by fingerprint, not by a
committed per-repo config. Beyond that there are no other command-level
subsystems: no variant/persona selection, no attach/cockpit framing. The
client is the read-only view; there's nothing separate to attach to.
The control invariant
An agent CLI must never block the system. The supervisor owns each agent's pty directly and runs a watchdog that classifies stream output as progress, stall (no-output-for-N), or an interactive-prompt pattern — any of which triggers auto-resolve, deny, or kill-and-reclaim. See Safety floors.
Discovery
The supervisor binds a Unix domain socket (a named pipe on Windows) at a
well-known path under the XDG runtime state root
(ipc.ServiceEndpoint: <state-root>/service.sock, heartbeat
service.sock.alive). Discovery is just dialing that socket:
- success → a supervisor is live
- failure → refuse, and print the command to start one
Single-instance is enforced by an exclusive flock on a PID lockfile, not by the socket bind — the PID lock plus heartbeat file distinguish a live supervisor from a stale socket left by a crashed one (dead PID → the next supervisor reclaims: remove the stale socket, take over).
Native Windows execution boundary
Native Windows supports foreground radioactive_ralph --supervisor under the
interactive user's identity as a limited control-plane path. Provider workers
remain unsupported because the pty layer returns ErrPTYUnsupported; WSL2 is
the supported functional Windows route. Native Windows does not support SCM
persistence in v0.22.
The rejected service defaulted to LocalSystem while consuming user-scoped
state, credentials, repositories, binary/config paths, and a pipe writable by
the broad interactive-user SID. That violates both the one-user authority
model and the local privilege boundary.
SCM support remains disabled until a new design binds the service to one explicit user SID, secures every service-consumed filesystem path and the control pipe to that identity, provides a real native worker pty, proves a provider-backed repository turn under the service token, and passes a clean native lifecycle end-to-end. The complete superseding contract is Native Windows SCM safety disable.
State: one user-level database, clean repos
All project, plan, config, and spend state lives in one user-level
SQLite database under the XDG state root — durable memory for every
registered project on the machine, not per-repo. There is no committed
config directory and no per-repo database. Never store Ralph runtime
state under .claude/.
Project identity
A project is identified by accumulated fingerprints, not an absolute path:
- a git directory fingerprints via git heuristics (root-commit sha, remote, repo-root markers)
- a non-git directory seeds with its absolute path
Identifiers accumulate: a directory that starts as path-only and is later
git init-ed gains its git fingerprints on top of the existing path
identifier, so the same project stays recognized across that transition
and across directory moves.
Config
Configuration resolves through virtual layers built by the supervisor
from the database plus three override flags
(--config-file/-C, --user-config-file, --project-config-file).
See Config virtual layers for the full
model.
Plans and completion
Plans are markdown, decomposed heuristically over a goldmark AST — no
LLM in decomposition. The orchestrator dispatches ready steps to agent
workers with plan-scoped context and verifies completion against
acceptance criteria; a worker's self-report or process termination is
never sufficient on its own. See Plan format
and Orchestrator-verified completion and
A2A.
Providers
Shipped providers: claude, codex, opencode — each a capability
record, not a persona. "Local-only" means the CLI owns its own agent loop
and tool execution locally, even when it calls a hosted model for
inference. gemini was removed (CLI auth endpoint deprecated
2026-06-18); cursor-agent is excluded (delegates session control to
Cursor's cloud). A project can select a singular provider or a
Ralph-managed provider pool; the latter creates one supervised worker per
admitted, dispatched step. The supervisor-wide RALPH_MAX_PARALLEL
environment setting bounds simultaneous workers. See Provider
contract and Config virtual
layers.
RALPH_MAX_PARALLEL is a process-local emergency ceiling, not adaptive
admission policy and not a statement of optimal team size. The current
compatibility default is unbounded when unset. Planned adaptive admission will
measure work class, provider lane, empirical independence domain, and host
pressure instead of assuming one fixed worker count.
