Skip to content

Commit fc023c4

Browse files
Kasper Jungeclaude
authored andcommitted
docs: update codebase map and changelog to reflect Primitive protocol and recent refactors
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 00f52c2 commit fc023c4

2 files changed

Lines changed: 14 additions & 10 deletions

File tree

docs/changelog.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,18 @@ Renamed "prompt" to "ralph" everywhere, simplified the CLI, and added a spinner
2424

2525
- Agent result message is now displayed in CLI output after each iteration.
2626
- Raw Claude Code `stream-json` output no longer leaks to the terminal during iterations.
27-
- Web dashboard page now clearly marked as "Coming Soon" to prevent users from trying non-existent commands.
27+
- Removed placeholder dashboard page so all docs describe real, shipping features.
2828

2929
### Improved
3030

31+
- Introduced `Primitive` protocol in `_discovery.py` so all four primitive types (`Check`, `Context`, `Instruction`, `Ralph`) share a typed interface for discovery, filtering, merging, and display.
32+
- Added generic `_discover_and_filter_enabled()` in the engine, replacing per-type boilerplate with a single code path bounded by the `Primitive` protocol.
33+
- Moved check result serialization into `CheckResult.to_event_data()` so event data formatting has a single source of truth.
34+
- Added missing event data fields (`result_text`, `detail`, `duration_formatted`) to API docs so library users see what the engine actually emits.
3135
- Extracted shared scanning logic in `_discovery.py` to reduce duplication across primitive types.
3236
- Added `PrimitiveEntry` type annotations for better code clarity.
3337
- Moved `merge_by_name` to `_discovery.py` and deduplicated checks discovery logic.
34-
- Updated codebase map and contributing docs to match the renamed source structure.
38+
- Updated codebase map and contributing docs to match the current architecture.
3539

3640
### Migration guide
3741

docs/contributing/codebase-map.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ src/ralphify/ # All source code
3030
├── _run_types.py # RunConfig, RunState, RunStatus — shared data types for the engine
3131
├── _runner.py # Execute shell commands with timeout and capture output (checks/contexts)
3232
├── _frontmatter.py # Parse YAML frontmatter from markdown primitives, marker/config constants
33-
├── _discovery.py # Scan .ralphify/ directories for primitives (discover_primitives, find_run_script)
33+
├── _discovery.py # Primitive protocol, directory scanning, merge_by_name, find_run_script
3434
├── _templates.py # Scaffold templates for init and new commands
3535
├── _console_emitter.py # Rich console renderer for run-loop events (ConsoleEmitter)
3636
├── _events.py # Event types and emitter protocol (NullEmitter, QueueEmitter, FanoutEmitter)
@@ -71,9 +71,9 @@ ralph run
7171
└── Repeat
7272
```
7373

74-
### The four primitives
74+
### The four primitives and the `Primitive` protocol
7575

76-
All four follow the same pattern: a directory under `.ralphify/` with a marker markdown file containing YAML frontmatter.
76+
All four primitive types follow the same pattern: a directory under `.ralphify/` with a marker markdown file containing YAML frontmatter. Each type's dataclass (`Check`, `Context`, `Instruction`, `Ralph`) satisfies the `Primitive` protocol defined in `_discovery.py`, which requires `name` and `enabled` properties. This enables type-safe generic functions for discovery, filtering, merging, and display — the engine's `_discover_and_filter_enabled()` helper uses the protocol to handle all four types through a single code path.
7777

7878
| Primitive | Marker file | Runs | Injects into prompt |
7979
|---|---|---|---|
@@ -82,7 +82,7 @@ All four follow the same pattern: a directory under `.ralphify/` with a marker m
8282
| Instruction | `INSTRUCTION.md` | Before iteration | Content replaces `{{ instructions.name }}` |
8383
| Ralph | `RALPH.md` | At run start | Replaces root RALPH.md when selected by name |
8484

85-
Discovery is handled by `_discovery.py:discover_primitives()` which scans `.ralphify/{kind}/*/` for marker files.
85+
Discovery is handled by `_discovery.py:discover_primitives()` which scans `.ralphify/{kind}/*/` for marker files. The engine groups enabled primitives into an `EnabledPrimitives` NamedTuple for clean parameter passing.
8686

8787
### Placeholder resolution
8888

@@ -98,7 +98,7 @@ The run loop communicates via structured events (`_events.py`). Each event has a
9898

9999
- **`EventEmitter`** — protocol that any listener implements (just an `emit(event)` method)
100100
- **`NullEmitter`** — discards events (used in tests)
101-
- **`QueueEmitter`** — pushes events into a `queue.Queue` for async consumption (used by the UI)
101+
- **`QueueEmitter`** — pushes events into a `queue.Queue` for async consumption (used by external orchestration layers)
102102
- **`FanoutEmitter`** — broadcasts events to multiple emitters (used by the manager for fan-out to queue + persistence)
103103

104104
The CLI uses a `ConsoleEmitter` (defined in `_console_emitter.py`) that renders events to the terminal with Rich formatting.
@@ -117,7 +117,7 @@ The CLI uses a `ConsoleEmitter` (defined in `_console_emitter.py`) that renders
117117
1. **`engine.py`** — The core run loop. Uses `RunConfig` and `RunState` (from `_run_types.py`) and `EventEmitter`. This is where iteration logic lives.
118118
2. **`_run_types.py`**`RunConfig`, `RunState`, and `RunStatus`. These are the shared data types used by the engine, CLI, and manager. Separated so modules that only need the types don't pull in execution logic.
119119
3. **`cli.py`** — All CLI commands. Delegates to `engine.run_loop()` for the actual loop. Prompt source resolution (name vs. file path vs. inline) lives in `ralphs.py:resolve_ralph_source()`. Scaffold templates live in `_templates.py`. Terminal event rendering lives in `_console_emitter.py`.
120-
4. **`_frontmatter.py`** + **`_discovery.py`** — Frontmatter parsing and primitive discovery. `_frontmatter.py` handles YAML parsing and defines marker constants. `_discovery.py` scans `.ralphify/` directories and uses `parse_frontmatter()` to yield `PrimitiveEntry` results. Understanding both is essential for working on checks/contexts/instructions/ralphs.
120+
4. **`_frontmatter.py`** + **`_discovery.py`** — Frontmatter parsing and primitive discovery. `_frontmatter.py` handles YAML parsing and defines marker constants. `_discovery.py` defines the `Primitive` protocol, scans `.ralphify/` directories, and provides `merge_by_name()` for overlaying ralph-scoped primitives on globals. Understanding both is essential for working on checks/contexts/instructions/ralphs.
121121
5. **`resolver.py`** — Template placeholder logic shared by contexts and instructions. Small file but critical — changes here affect both.
122122

123123
## Traps and gotchas
@@ -138,9 +138,9 @@ Add it in `cli.py`. The CLI uses Typer. The `new` subcommand group uses `app.add
138138

139139
You need to:
140140

141-
1. Create a new module (like `ralphs.py`) with dataclass, discover, and resolve functions
141+
1. Create a new module (like `ralphs.py`) with a dataclass that satisfies the `Primitive` protocol (`name` and `enabled` properties), plus discover and resolve functions
142142
2. Add a scaffold template in `_templates.py` and a `new` subcommand in `cli.py`
143-
3. Wire it into `engine.py:run_loop()` if it affects the iteration cycle
143+
3. Wire it into `engine.py:run_loop()` — add it to `EnabledPrimitives` and use `_discover_and_filter_enabled()`
144144
4. Add tests
145145
5. Update `docs/primitives.md`
146146

0 commit comments

Comments
 (0)