All skills
Skillintermediate
Event System Research
**File:** `crates/ralph-proto/src/event.rs`
Claude Code Knowledge Pack7/10/2026
Overview
Event System Research
Event Structure
File: crates/ralph-proto/src/event.rs
pub struct Event {
pub topic: Topic, // Routing key (e.g., "build.done")
pub payload: String, // Content/data (string or JSON-stringified)
pub source: Option, // Hat that published
pub target: Option, // Direct target for handoff (bypasses subscription routing)
}
Key observations:
- No correlation ID, wave ID, or batch metadata today
targetallows direct hat-to-hat handoff- Payload is always a string (JSON objects are stringified)
Event Bus
File: crates/ralph-proto/src/event_bus.rs
pub struct EventBus {
hats: BTreeMap<HatId, Hat>,
pending: BTreeMap<HatId, Vec>, // Queue of events per hat
human_pending: Vec, // Separate queue for human.* events
observers: Vec, // Observer callbacks
}
Routing flow:
- Observers notified first (enables session recording)
- If
event.targetset → route only to target hat - Otherwise → match topic against hat subscriptions (specific > wildcard)
- Events with
human.*topic go to separate queue
Key methods:
publish(event) -> Vec— returns recipientstake_pending(&hat_id) -> Vec— destructive consumenext_hat_with_pending()— BTreeMap order, first hat with events
Event Emission from Agents
File: crates/ralph-cli/src/main.rs:2249-2317
ralph emit <topic> [--payload "text"] [--json] [--ts] [--file]
Flow:
- Builds JSON record with topic, payload, ts
- Reads
.ralph/current-eventsmarker to find active events file - Falls back to
.ralph/events.jsonl - Appends single JSONL line atomically
No direct EventBus interaction — events written to file, read by EventReader.
Event Reading
File: crates/ralph-core/src/event_reader.rs
- Incremental reading (tracks file position)
- Handles both string and object payloads
- Returns
ParseResultwith events + malformed lines for backpressure
Event Logging
File: crates/ralph-core/src/event_logger.rs
pub struct EventRecord {
pub ts: String,
pub iteration: u32,
pub hat: String,
pub topic: String,
pub triggered: Option,
pub payload: String, // Truncated to 500 chars
pub blocked_count: Option<u32>,
}
Extension Points for Waves
Adding wave/correlation metadata requires changes to:
- Event struct — Add
wave_id: Option,wave_index: Option<u32>,wave_total: Option<u32> - EventRecord — Add corresponding optional fields (skip_serializing_if)
- EventBus — Track active waves, buffer correlated events, completion conditions
- EventReader — Parse new fields from JSONL
ralph emit— Add--wave-id,--wave-index,--wave-totalflags
The architecture supports optional fields well — serde skip_serializing_if is used throughout.
Topic Matching
File: crates/ralph-proto/src/topic.rs
Supports glob-style patterns:
- Exact:
impl.done - Suffix wildcard:
impl.* - Prefix wildcard:
*.done - Global wildcard:
*