All skills
Skillintermediate

Architecture

Ralph's system architecture and how the pieces fit together.

Claude Code Knowledge Pack7/10/2026

Overview

Architecture

Ralph's system architecture and how the pieces fit together.

Overview

Ralph is a Cargo workspace with seven crates, each with a specific responsibility:

┌─────────────────────────────────────────────────────────┐
│                      ralph-cli                          │
│                  (Binary Entry Point)                   │
├─────────────┬─────────────┬─────────────┬──────────────┤
│ ralph-core  │ralph-adapters│  ralph-tui  │ ralph-e2e   │
│  (Engine)   │ (Backends)   │    (UI)     │  (Testing)  │
├─────────────┴─────────────┴─────────────┴──────────────┤
│                     ralph-proto                         │
│                  (Protocol Types)                       │
└─────────────────────────────────────────────────────────┘

Crate Responsibilities

ralph-proto

Protocol types shared across all crates.

Key types:

TypePurpose
EventMessage with topic, payload, source/target hat
HatPersona definition (triggers, publishes, instructions)
HatIdUnique hat identifier
TopicEvent routing with glob patterns
EventBusHat registry and event routing

Location: crates/ralph-proto/src/

ralph-core

The orchestration engine.

Key components:

ModulePurpose
EventLoopMain orchestration loop
configYAML configuration loading
event_parserParse agent output for events
memory_storePersistent memory management
task_storeTask storage and querying
instructionsHat instruction assembly

Location: crates/ralph-core/src/

ralph-adapters

CLI backend integrations.

Key components:

ModulePurpose
CliBackendBackend definition
pty_executorPTY-based execution
stream_handlerOutput handlers
auto_detectBackend availability detection

Supported backends:

  • Claude Code
  • Kiro
  • Gemini CLI
  • Codex
  • Amp
  • Copilot CLI
  • OpenCode

Location: crates/ralph-adapters/src/

ralph-tui

Terminal UI using ratatui.

Features:

  • Real-time iteration display
  • Elapsed time tracking
  • Hat emoji and name display
  • Activity indicator
  • Event topic display

Location: crates/ralph-tui/src/

ralph-cli

Binary entry point and CLI parsing.

Commands:

  • ralph run — Execute orchestration
  • ralph init — Initialize config
  • ralph plan — PDD planning
  • ralph task — Task generation
  • ralph events — View history
  • ralph tools — Memory/task management

Location: crates/ralph-cli/src/

ralph-e2e

End-to-end testing framework.

Test tiers:

TierFocus
1Connectivity
2Orchestration Loop
3Events
4Capabilities
5Hat Collections
6Memory System
7Error Handling

Location: crates/ralph-e2e/src/

ralph-bench

Benchmarking harness (development only).

Location: crates/ralph-bench/src/

Data Flow

Traditional Mode

flowchart TD
    A[PROMPT.md] --> B[ralph-cli]
    B --> C[ralph-core EventLoop]
    C --> D[ralph-adapters Backend]
    D --> E[AI CLI]
    E --> F[Output]
    F --> G{LOOP_COMPLETE?}
    G -->|No| C
    G -->|Yes| H[Done]

Hat-Based Mode

flowchart TD
    A[starting_event] --> B[EventBus]
    B --> C{Match Hat?}
    C -->|Yes| D[Inject Instructions]
    D --> E[Execute Backend]
    E --> F[Parse Output]
    F --> G{Event Emitted?}
    G -->|Yes| H[Route Event]
    H --> B
    G -->|No| I{LOOP_COMPLETE?}
    I -->|Yes| J[Done]
    I -->|No| B

State Management

Files on Disk

All persistent state lives in .agent/:

.agent/
├── memories.md         # Persistent learning
├── tasks.jsonl         # Runtime work tracking
├── event_history.jsonl # Event audit log
└── scratchpad.md       # Iteration state (per-hat scratchpads may also exist)

Event Bus

In-memory during execution:

struct EventBus {
    hats: HashMap<HatId, Hat>,
    pending_events: VecDeque,
    event_history: Vec,
}

Configuration

Loaded from ralph.yml:

struct Config {
    cli: CliConfig,
    event_loop: EventLoopConfig,
    core: CoreConfig,
    memories: MemoryConfig,
    tasks: TaskConfig,
    hats: HashMap<String, HatConfig>,
}

Process Model

Unix Process Groups

Ralph manages processes carefully:

  • Creates process group leadership
  • Handles SIGINT, SIGTERM gracefully
  • Prevents orphan processes
  • Restores terminal state on exit

PTY Handling

For real-time output capture:

// Async PTY execution with stream handling
pty_executor.execute(command, stream_handler).await

Async Architecture

Ralph uses Tokio throughout:

  • Async trait support
  • Stream-based output capture
  • Concurrent PTY handling
  • Non-blocking TUI updates

Error Handling

Custom error types with context:

// thiserror for type definitions
#[derive(Error, Debug)]
enum RalphError {
    #[error("Configuration error: {0}")]
    Config(String),
    // ...
}

// anyhow for context
fn load_config() -> Result {
    read_file(path).context("Failed to load config")?
}

Extension Points

Custom Backends

Implement CliBackend trait:

struct MyBackend;

impl CliBackend for MyBackend {
    fn command(&self) -> &str { "my-cli" }
    fn prompt_mode(&self) -> PromptMode { PromptMode::Arg }
}

Custom Stream Handlers

Implement StreamHandler trait:

struct MyHandler;

impl StreamHandler for MyHandler {
    fn on_output(&mut self, chunk: &str) { ... }
    fn on_complete(&mut self) { ... }
}

Performance Considerations

Context Window

Optimize for "smart zone" (40-60% of tokens):

  • Memory injection has configurable budget
  • Instructions are assembled efficiently
  • Large outputs are truncated

Token Efficiency

  • Events are routing signals, not data transport
  • Detailed output goes to memories
  • Event payloads are kept small

Next Steps