Skip to content

Commit 42c07ff

Browse files
committed
docs: align goal session specs with /goal
1 parent 8424c25 commit 42c07ff

5 files changed

Lines changed: 82 additions & 81 deletions

File tree

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
# 2026-04-27-ralph-session-loop-plugin
22

3-
Track the phase-1 design for introducing Ralph session-loop commands in AWorld.
3+
Track the phase-1 design lineage that ultimately landed as the shared `/goal` session loop in AWorld.
44

55
Implementation note:
66

7-
- the user-facing Ralph commands remain `/ralph-loop` and `/cancel-ralph`
8-
- the shared persisted contract now lives in the built-in `goal-session` plugin
7+
- the user-facing entrypoint is now `/goal`
8+
- `/goal "..."` starts a session goal directly
9+
- `/goal status`, `/goal pause`, and `/goal clear` control the persisted goal state
910
- continuation is driven from task lifecycle hooks, while the `stop` hook only blocks accidental exit from an active goal

openspec/changes/2026-04-27-ralph-session-loop-plugin/design.md

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ The current `RalphRunner` is not the right primary abstraction for this phase be
4040
- Do not implement fresh-process or fresh-session orchestration in phase 1.
4141
- Do not execute verification commands inside the stop hook in phase 1.
4242
- Do not add phase-1 loop-local runtime overrides such as `--model` or `--work-dir`.
43-
- Do not introduce Claude-specific state files such as `.claude/ralph-loop.local.md`.
43+
- Do not introduce Claude-specific state files such as `.claude/goal.local.md`.
4444
- Do not redesign the general plugin framework as part of this change.
4545

4646
## Decisions
@@ -51,9 +51,10 @@ The first AWorld Ralph capability should be implemented as a normal plugin, not
5151

5252
The plugin should own these entrypoints:
5353

54-
- `commands/ralph-loop.md`
55-
- `commands/cancel-ralph.md`
56-
- `hooks/stop_hook.py`
54+
- `hooks/stop.py`
55+
- `hooks/task_completed.py`
56+
- `hooks/task_error.py`
57+
- `hooks/task_interrupted.py`
5758
- `hud/status.py`
5859
- `.aworld-plugin/plugin.json`
5960

@@ -83,7 +84,7 @@ Implications:
8384

8485
- the phase-1 plugin must not invoke `RalphRunner` implicitly
8586
- the plugin must not treat `RalphRunner` as the only way AWorld can expose Ralph semantics
86-
- plugin `--max-iterations` applies only to session continuation
87+
- plugin `--max-turns` applies only to session continuation
8788
- runner `completion_criteria.max_iterations` applies only to inner task execution
8889
- phase 1 does not define a priority or override relationship between those two limits
8990

@@ -97,7 +98,7 @@ Why:
9798

9899
The phase-1 control path should be:
99100

100-
1. `/ralph-loop` initializes loop state.
101+
1. `/goal "..."` initializes loop state.
101102
2. The current session executes the task.
102103
3. The shared `goal-session` task lifecycle hooks update turn state and decide whether unfinished work should continue immediately.
103104
4. When the operator attempts to exit, the `goal-session` `stop` hook only decides whether exit is safe, paused, or should be denied.
@@ -128,7 +129,7 @@ Recommended minimum state shape:
128129
"pytest tests/api -q",
129130
"ruff check ."
130131
],
131-
"source": "ralph_compat",
132+
"source": "goal",
132133
"started_at": "2026-04-27T10:00:00Z",
133134
"last_task_status": "initialized",
134135
"last_final_answer_excerpt": null
@@ -146,18 +147,18 @@ Why:
146147
- The plugin framework already exposes persisted state APIs.
147148
- It avoids introducing a second state persistence model just for Ralph.
148149

149-
### Decision: `/ralph-loop` stores structured verify requirements in goal-session state, but hooks do not run them
150+
### Decision: `/goal` stores structured verify requirements in goal-session state, but hooks do not run them
150151

151152
Phase-1 verification requirements should be declared structurally and then injected into the effective prompt.
152153

153154
Recommended user-facing contract:
154155

155156
```text
156-
/ralph-loop "Implement the todo API" \
157+
/goal "Implement the todo API" \
157158
--verify "pytest tests/api -q" \
158159
--verify "ruff check ." \
159160
--completion-promise "COMPLETE" \
160-
--max-iterations 20
161+
--max-turns 20
161162
```
162163

163164
The plugin should persist these `verification_commands` in goal-session state and normalize the working prompt into a goal contract similar to:
@@ -167,7 +168,7 @@ The plugin should persist these `verification_commands` in goal-session state an
167168
Objective: Implement the todo API
168169
Status: active
169170
Turns: 1/20
170-
Source: ralph_compat
171+
Source: goal
171172
Verification commands:
172173
1. pytest tests/api -q
173174
2. ruff check .
@@ -245,12 +246,12 @@ Why:
245246

246247
### Command Contract
247248

248-
`/ralph-loop`
249+
`/goal`
249250

250251
- accepts task prompt text
251252
- accepts repeatable `--verify`
252253
- accepts optional `--completion-promise`
253-
- accepts optional `--max-iterations`
254+
- accepts optional `--max-turns`
254255
- initializes or replaces the active Ralph session state
255256
- emits a confirmation message describing the active loop policy
256257

@@ -259,10 +260,10 @@ Explicitly deferred from the phase-1 command surface:
259260
- `--model`
260261
- `--work-dir`
261262

262-
`/cancel-ralph`
263+
`/goal clear`
263264

264-
- clears the active Ralph loop state
265-
- emits a confirmation message describing that the loop has been cancelled
265+
- clears the active goal loop state
266+
- emits a confirmation message describing that the loop has been cleared
266267

267268
### Hook Contract
268269

@@ -296,8 +297,8 @@ The HUD provider reads plugin state and renders status lines only.
296297
Phase-1 validation should cover:
297298

298299
- command registration and manifest loading
299-
- `/ralph-loop` state initialization
300-
- `/cancel-ralph` state clearing
300+
- `/goal` state initialization
301+
- `/goal clear` state clearing
301302
- `/goal` status, pause, and clear behavior
302303
- task-completed continuation behavior
303304
- exact completion-promise match behavior
@@ -309,11 +310,11 @@ Phase-1 validation should cover:
309310
Recommended simple acceptance cases for phase 1:
310311

311312
- default unbounded loop:
312-
`/ralph-loop "Build a Python course"`
313+
`/goal "Build a Python course"`
313314
- explicit iteration cap:
314-
`/ralph-loop "Build a REST API" --max-iterations 5`
315+
`/goal "Build a REST API" --max-turns 5`
315316
- declarative verification:
316-
`/ralph-loop "Create a CLI tool" --verify "pytest tests/cli -q" --completion-promise "COMPLETE"`
317+
`/goal "Create a CLI tool" --verify "pytest tests/cli -q" --completion-promise "COMPLETE"`
317318

318319
Examples intentionally not adopted as phase-1 acceptance cases:
319320

openspec/changes/2026-04-27-ralph-session-loop-plugin/implementation-plan.md

Lines changed: 48 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
# Ralph Session Loop Plugin Implementation Plan
1+
# Goal Session Loop Implementation Plan
22

3-
> Historical note: this implementation plan predates the shared `goal-session` refactor. The shipped phase-1 behavior keeps `/ralph-loop` and `/cancel-ralph`, but uses the built-in `goal-session` plugin as the single persisted contract and loop-control surface.
3+
> Historical note: this implementation plan predates the final command unification. The shipped phase-1 behavior uses the built-in `goal-session` plugin as the single persisted contract and exposes `/goal` as the only user-facing command surface.
44
55
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
66
7-
**Goal:** Build a standalone phase-1 Ralph plugin for the interactive AWorld CLI that loops within the current session using plugin commands, plugin state, and stop hooks.
7+
**Goal:** Build a standalone phase-1 session-goal loop for the interactive AWorld CLI that runs within the current session using plugin commands, plugin state, and stop hooks.
88

9-
**Architecture:** Extend plugin commands so a plugin can contribute Python-backed slash commands in addition to markdown prompt commands. Implement a built-in Ralph plugin with a prompt command for `/ralph-loop`, a tool command for `/cancel-ralph`, task-state hooks for final-answer diagnostics, a stop hook for continuation, and a HUD provider for loop status.
9+
**Architecture:** Extend plugin commands so a plugin can contribute Python-backed slash commands in addition to markdown prompt commands. Implement a built-in goal-session plugin with a slash command that starts a goal via `/goal "..."`, handles exact control actions for `/goal status`, `/goal pause`, and `/goal clear`, and uses task-state hooks plus a HUD provider for loop status.
1010

1111
**Tech Stack:** Python, pytest, AWorld CLI plugin framework, plugin state store, command registry, plugin hooks, HUD providers
1212

@@ -27,7 +27,7 @@ Add tests that require:
2727
```python
2828
def test_register_python_backed_plugin_command_from_manifest():
2929
...
30-
command = CommandRegistry.get("ralph-loop")
30+
command = CommandRegistry.get("goal")
3131
assert command is not None
3232
assert command.command_type == "prompt"
3333

@@ -71,38 +71,37 @@ else:
7171
Run: `pytest tests/plugins/test_plugin_commands.py -k "python_backed or session_id" -v`
7272
Expected: PASS
7373

74-
### Task 2: Built-in Ralph Plugin Commands
74+
### Task 2: Built-in Goal Plugin Commands
7575

7676
**Files:**
77-
- Create: `aworld-cli/src/aworld_cli/builtin_plugins/ralph_session_loop/.aworld-plugin/plugin.json`
78-
- Create: `aworld-cli/src/aworld_cli/builtin_plugins/ralph_session_loop/__init__.py`
79-
- Create: `aworld-cli/src/aworld_cli/builtin_plugins/ralph_session_loop/commands/ralph_loop.py`
80-
- Create: `aworld-cli/src/aworld_cli/builtin_plugins/ralph_session_loop/commands/cancel_ralph.py`
77+
- Create: `aworld-cli/src/aworld_cli/builtin_plugins/goal_session/.aworld-plugin/plugin.json`
78+
- Create: `aworld-cli/src/aworld_cli/builtin_plugins/goal_session/common.py`
79+
- Create: `aworld-cli/src/aworld_cli/builtin_plugins/goal_session/hooks/stop.py`
8180
- Test: `tests/plugins/test_plugin_commands.py`
8281

83-
- [ ] **Step 1: Write the failing tests for `/ralph-loop` and `/cancel-ralph` state behavior**
82+
- [ ] **Step 1: Write the failing tests for `/goal "..."` and `/goal clear` state behavior**
8483

8584
Add tests that require:
8685

8786
```python
88-
async def test_ralph_loop_command_initializes_session_state(tmp_path):
87+
async def test_goal_command_initializes_session_state(tmp_path):
8988
...
9089
payload = json.loads(state_path.read_text())
9190
assert payload["active"] is True
92-
assert payload["iteration"] == 1
93-
assert payload["verify_commands"] == ["pytest tests/api -q"]
91+
assert payload["turn_count"] == 1
92+
assert payload["verification_commands"] == ["pytest tests/api -q"]
9493

95-
async def test_cancel_ralph_clears_session_state(tmp_path):
94+
async def test_goal_clear_clears_session_state(tmp_path):
9695
...
9796
result = await command.execute(context)
98-
assert "cancelled" in result.lower()
97+
assert "cleared" in result.lower()
9998
assert handle.read() == {}
10099
```
101100

102101
- [ ] **Step 2: Run the focused tests to verify they fail**
103102

104-
Run: `pytest tests/plugins/test_plugin_commands.py -k "ralph_loop_command or cancel_ralph" -v`
105-
Expected: FAIL because the built-in plugin and command modules do not exist yet.
103+
Run: `pytest tests/plugins/test_plugin_commands.py -k "goal_command" -v`
104+
Expected: FAIL because the built-in goal-session command behavior does not exist yet.
106105

107106
- [ ] **Step 3: Implement the built-in plugin commands with minimal argument parsing**
108107

@@ -111,13 +110,13 @@ Required behavior:
111110
```python
112111
state = {
113112
"active": True,
114-
"prompt": prompt_text,
115-
"iteration": 1,
116-
"max_iterations": max_iterations,
113+
"status": "active",
114+
"objective": prompt_text,
115+
"turn_count": 1,
116+
"max_turns": max_turns,
117117
"completion_promise": completion_promise,
118-
"verify_commands": verify_commands,
118+
"verification_commands": verify_commands,
119119
"started_at": started_at,
120-
"last_stop_reason": None,
121120
"last_final_answer_excerpt": None,
122121
}
123122
```
@@ -137,17 +136,17 @@ Completion rule:
137136

138137
- [ ] **Step 4: Run the focused tests to verify they pass**
139138

140-
Run: `pytest tests/plugins/test_plugin_commands.py -k "ralph_loop_command or cancel_ralph" -v`
139+
Run: `pytest tests/plugins/test_plugin_commands.py -k "goal_command" -v`
141140
Expected: PASS
142141

143-
### Task 3: Ralph Hooks And HUD
142+
### Task 3: Goal Hooks And HUD
144143

145144
**Files:**
146-
- Create: `aworld-cli/src/aworld_cli/builtin_plugins/ralph_session_loop/hooks/task_completed.py`
147-
- Create: `aworld-cli/src/aworld_cli/builtin_plugins/ralph_session_loop/hooks/task_error.py`
148-
- Create: `aworld-cli/src/aworld_cli/builtin_plugins/ralph_session_loop/hooks/task_interrupted.py`
149-
- Create: `aworld-cli/src/aworld_cli/builtin_plugins/ralph_session_loop/hooks/stop.py`
150-
- Create: `aworld-cli/src/aworld_cli/builtin_plugins/ralph_session_loop/hud/status.py`
145+
- Create: `aworld-cli/src/aworld_cli/builtin_plugins/goal_session/hooks/task_completed.py`
146+
- Create: `aworld-cli/src/aworld_cli/builtin_plugins/goal_session/hooks/task_error.py`
147+
- Create: `aworld-cli/src/aworld_cli/builtin_plugins/goal_session/hooks/task_interrupted.py`
148+
- Create: `aworld-cli/src/aworld_cli/builtin_plugins/goal_session/hooks/stop.py`
149+
- Create: `aworld-cli/src/aworld_cli/builtin_plugins/goal_session/hud/status.py`
151150
- Test: `tests/plugins/test_plugin_hooks.py`
152151
- Test: `tests/plugins/test_plugin_hud.py`
153152

@@ -156,23 +155,23 @@ Expected: PASS
156155
Add tests that require:
157156

158157
```python
159-
async def test_ralph_stop_hook_blocks_and_continues_when_active(...):
158+
async def test_goal_task_completed_hook_blocks_and_continues_when_active(...):
160159
assert result.action == "block_and_continue"
161-
assert "Task:" in result.follow_up_prompt
160+
assert "<goal_contract>" in result.follow_up_prompt
162161

163-
async def test_ralph_stop_hook_allows_exit_on_exact_completion_promise(...):
164-
assert result.action == "allow"
162+
async def test_goal_stop_hook_denies_exit_when_goal_is_active(...):
163+
assert result.action == "deny"
165164

166-
async def test_ralph_stop_hook_allows_exit_when_max_iterations_reached(...):
165+
async def test_goal_task_completed_hook_marks_goal_complete_on_exact_completion_promise(...):
167166
assert result.action == "allow"
168167

169-
def test_ralph_hud_renders_active_state(...):
170-
assert any("Ralph: active" in segment for segment in lines[0].segments + lines[1].segments)
168+
def test_goal_hud_renders_active_state(...):
169+
assert any("Goal: active" in segment for segment in lines[0].segments + lines[1].segments)
171170
```
172171

173172
- [ ] **Step 2: Run the focused tests to verify they fail**
174173

175-
Run: `pytest tests/plugins/test_plugin_hooks.py tests/plugins/test_plugin_hud.py -k "ralph" -v`
174+
Run: `pytest tests/plugins/test_plugin_hooks.py tests/plugins/test_plugin_hud.py -k "goal" -v`
176175
Expected: FAIL because the hook and HUD modules do not exist yet.
177176

178177
- [ ] **Step 3: Implement task-state hooks, stop hook, and HUD provider**
@@ -192,18 +191,18 @@ Stop hook policy:
192191
if not active:
193192
return {"action": "allow"}
194193
if completion promise matched:
195-
handle.clear()
194+
handle.update({"status": "complete", "active": False})
196195
return {"action": "allow"}
197-
if max iterations reached:
198-
handle.clear()
196+
if max turns reached:
197+
handle.update({"status": "budget_limited", "active": False})
199198
return {"action": "allow"}
200-
handle.update({"iteration": next_iteration, ...})
199+
handle.update({"turn_count": next_turn, ...})
201200
return {"action": "block_and_continue", "follow_up_prompt": normalized_prompt}
202201
```
203202

204203
- [ ] **Step 4: Run the focused tests to verify they pass**
205204

206-
Run: `pytest tests/plugins/test_plugin_hooks.py tests/plugins/test_plugin_hud.py -k "ralph" -v`
205+
Run: `pytest tests/plugins/test_plugin_hooks.py tests/plugins/test_plugin_hud.py -k "goal" -v`
207206
Expected: PASS
208207

209208
### Task 4: Runtime Integration
@@ -217,16 +216,16 @@ Expected: PASS
217216
Add a test that:
218217

219218
```python
220-
1. loads the built-in Ralph plugin
221-
2. executes `/ralph-loop ...`
219+
1. loads the built-in goal plugin
220+
2. executes `/goal ...`
222221
3. simulates a completed task hook update without promise match
223222
4. runs the stop hook
224223
5. asserts `block_and_continue` and iteration increment
225224
```
226225

227226
- [ ] **Step 2: Run the focused integration test to verify it fails**
228227

229-
Run: `pytest tests/plugins/test_plugin_end_to_end.py -k "ralph" -v`
228+
Run: `pytest tests/plugins/test_plugin_end_to_end.py -k "goal" -v`
230229
Expected: FAIL until the full plugin surface is wired together.
231230

232231
- [ ] **Step 3: Implement any missing glue and keep scope minimal**
@@ -235,7 +234,7 @@ Only fill gaps required to make the built-in plugin work through the existing pl
235234

236235
- [ ] **Step 4: Run the focused integration test to verify it passes**
237236

238-
Run: `pytest tests/plugins/test_plugin_end_to_end.py -k "ralph" -v`
237+
Run: `pytest tests/plugins/test_plugin_end_to_end.py -k "goal" -v`
239238
Expected: PASS
240239

241240
### Task 5: Final Verification
@@ -245,9 +244,9 @@ Expected: PASS
245244

246245
- [ ] **Step 1: Mark completed OpenSpec tasks that were actually implemented**
247246

248-
- [ ] **Step 2: Run the complete Ralph-related verification suite**
247+
- [ ] **Step 2: Run the complete goal-related verification suite**
249248

250-
Run: `pytest tests/plugins/test_plugin_commands.py tests/plugins/test_plugin_hooks.py tests/plugins/test_plugin_hud.py tests/plugins/test_plugin_end_to_end.py -k "ralph or python_backed or session_id" -v`
249+
Run: `pytest tests/plugins/test_plugin_commands.py tests/plugins/test_plugin_hooks.py tests/plugins/test_plugin_hud.py tests/plugins/test_plugin_end_to_end.py -k "goal or python_backed or session_id" -v`
251250
Expected: PASS
252251

253252
- [ ] **Step 3: Run manifest and runtime regression checks around the touched plugin framework paths**

openspec/changes/2026-04-27-ralph-session-loop-plugin/proposal.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ For AWorld, phase 1 should optimize for the smallest clean integration boundary:
2222
## What Changes
2323

2424
- Introduce a standalone AWorld goal-session controller plugin that provides the shared in-session loop contract for the interactive CLI.
25-
- Keep `/ralph-loop` and `/cancel-ralph` as compatibility-facing Ralph commands layered on top of that shared goal-session state.
25+
- Use `/goal` as the only user-facing command surface for starting and controlling that shared goal-session state.
2626
- Define the phase-1 plugin shape around:
2727
- prompt commands
2828
- task lifecycle hooks that update and continue the active goal
@@ -37,8 +37,8 @@ For AWorld, phase 1 should optimize for the smallest clean integration boundary:
3737

3838
### New Capabilities
3939

40-
- `ralph-session-loop-plugin`: Adds a standalone plugin-hosted Ralph interaction model for the AWorld interactive CLI.
41-
- `goal-session-plugin`: Adds the shared persisted goal contract and exit-control surface used by Ralph compatibility commands.
40+
- `ralph-session-loop-plugin`: Tracks the original design lineage for the interactive session loop that now ships as `/goal`.
41+
- `goal-session-plugin`: Adds the shared persisted goal contract and exit-control surface used by `/goal`.
4242

4343
### Modified Capabilities
4444

@@ -47,7 +47,7 @@ For AWorld, phase 1 should optimize for the smallest clean integration boundary:
4747
## Impact
4848

4949
- Affects plugin manifests and plugin entrypoint usage under the AWorld CLI plugin framework.
50-
- Affects the interactive CLI experience by adding Ralph-specific slash commands plus a shared goal-status surface (`/goal`) for pause, clear, and status inspection.
50+
- Affects the interactive CLI experience by adding a single `/goal` slash-command surface for start, pause, clear, and status inspection.
5151
- Moves continuation control to task lifecycle hooks while leaving stop-hook behavior focused on exit gating.
5252
- Does not require `aworld/core` changes for phase 1.
5353
- Does not require `RalphRunner` changes for phase 1.

0 commit comments

Comments
 (0)