ralph-teams 1.0.29 → 1.0.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -82,4 +82,4 @@ A single implementation plan Markdown file written to the exact path the Team Le
82
82
  - Stay at design level. You may include signatures and contracts, but do not include full function bodies, code blocks, or pseudocode.
83
83
  - Design the test strategy per story, not just the code changes.
84
84
  - Reference existing patterns and keep the plan practical.
85
- - Your final response should confirm the exact plan file path you wrote.
85
+ - Your final response must include a line exactly in the form `WROTE: <path>` using the exact plan file path you wrote.
@@ -10,14 +10,21 @@ Start by reading `prompts/team-lead-policy.md`. That file is the canonical Team
10
10
 
11
11
  ## Claude-Specific Rules
12
12
 
13
- - Use Claude subagents, not direct teammate mailboxes.
14
- - When the policy says to spawn the story planner, use `subagent_type: "story-planner"`.
15
- - When the policy says to spawn the epic planner, use `subagent_type: "epic-planner"`.
16
- - When the policy says to spawn the Builder, spawn a fresh Builder with `subagent_type: "builder"`.
17
- - When the policy says to spawn the story validator, use `subagent_type: "story-validator"`.
18
- - When the policy says to spawn the epic validator, use `subagent_type: "epic-validator"`.
19
- - When the policy says to spawn the final validator, use `subagent_type: "final-validator"`.
20
- - Do NOT use `SendMessage` or `shutdown_request` to coordinate story execution.
13
+ - Use Claude agent teams, not Claude subagents.
14
+ - Create teammates with `TeamCreate` when you need planners, builders, validators, or a merger.
15
+ - When creating a teammate, give it the role-specific canonical prompt file to follow:
16
+ - epic planner -> `prompts/agents/epic-planner.md`
17
+ - story planner -> `prompts/agents/story-planner.md`
18
+ - builder -> `prompts/agents/builder.md`
19
+ - story validator -> `prompts/agents/story-validator.md`
20
+ - epic validator -> `prompts/agents/epic-validator.md`
21
+ - final validator -> `prompts/agents/final-validator.md`
22
+ - merger -> `prompts/agents/merger.md`
23
+ - Use `SendMessage` for follow-up instructions, task assignment, redirection, and clean teammate shutdown when needed.
24
+ - Use direct teammate messaging to coordinate planner and builder work when useful, but keep validators independent from builder reasoning. Validators should validate from acceptance criteria, plan context, code state, and commit results.
25
+ - Builder-to-validator direct messaging is restricted to artifact or status handoff only, such as commit SHAs, verification command completion, changed-file summaries, or artifact/result paths. Do not let the Builder send reasoning, verdict framing, acceptance-criteria arguments, or coaching about what the Validator should conclude.
26
+ - Keep Builder and Validator execution one-shot per attempt even though teammates can communicate. Create a fresh Builder for each build attempt and a fresh Validator for each validation attempt.
27
+ - When the epic is done, clean up the team state and shut down unneeded teammates instead of leaving them idle.
21
28
 
22
29
  ## Claude Model Selection Policy
23
30
 
@@ -79,5 +79,5 @@ A single implementation plan Markdown file written to the exact path the Team Le
79
79
  - Stay at design level. You may include signatures and contracts, but do not include full function bodies, code blocks, or pseudocode.
80
80
  - Design the test strategy per story, not just the code changes.
81
81
  - Reference existing patterns and keep the plan practical.
82
- - Your final response should confirm the exact plan file path you wrote.
82
+ - Your final response must include a line exactly in the form `WROTE: <path>` using the exact plan file path you wrote.
83
83
  """
@@ -82,4 +82,4 @@ A single implementation plan Markdown file written to the exact path the Team Le
82
82
  - Stay at design level. You may include signatures and contracts, but do not include full function bodies, code blocks, or pseudocode.
83
83
  - Design the test strategy per story, not just the code changes.
84
84
  - Reference existing patterns and keep the plan practical.
85
- - Your final response should confirm the exact plan file path you wrote.
85
+ - Your final response must include a line exactly in the form `WROTE: <path>` using the exact plan file path you wrote.
@@ -82,4 +82,4 @@ A single implementation plan Markdown file written to the exact path the Team Le
82
82
  - Stay at design level. You may include signatures and contracts, but do not include full function bodies, code blocks, or pseudocode.
83
83
  - Design the test strategy per story, not just the code changes.
84
84
  - Reference existing patterns and keep the plan practical.
85
- - Your final response should confirm the exact plan file path you wrote.
85
+ - Your final response must include a line exactly in the form `WROTE: <path>` using the exact plan file path you wrote.
package/README.md CHANGED
@@ -1,7 +1,10 @@
1
- # ralph-teams
1
+ # ralph-teams - Loop epics and ai teams, Trust the Team-Lead, Run and Walk away
2
2
 
3
- Lightweight orchestration for spec-driven AI delivery: Ralph Teams loops whole teams and epics, not tiny tasks, and uses small agent teams to move from PRD to merged implementation with minimal process overhead.
4
- It is built for teams who want the structure of epics and user stories without the token burn and rigidity of heavier spec-execution systems.
3
+ Lightweight orchestration for spec-driven AI delivery: Ralph Teams loops whole teams and epics, not tiny tasks, and uses small agent teams to move from PRD to merged implementation with minimal process overhead.
4
+
5
+ The Teamlead decides on which agent to spawn and which model to use depending on the task complexity.
6
+
7
+ It is built for developer who don't want to babysit their agents. Start the loop and walk away.
5
8
 
6
9
  `ralph-teams` is a lightweight and budgetfriendly CLI for running Ralph Teams: a shell-based orchestrator that initializes and reads a `prd.json`, loops through epics (not user stories), and spawns AI coding agent teams to implement work story by story. One Agent Team per Epic with fresh context. Ralph-Teams can even work on multiple epics in parallel, if there are no dependencies
7
10
  ```bash
@@ -16,6 +16,11 @@ interface TaskDeps {
16
16
  }
17
17
  export declare function buildTaskPlanningPrompt(task: string, cwd: string, branch: string): string;
18
18
  export declare function buildTaskExecutionPrompt(task: string, cwd: string, branch: string): string;
19
+ export declare function buildTaskExecutionInvocation(backend: SupportedBackend, env: NodeJS.ProcessEnv): {
20
+ command: string;
21
+ args: string[];
22
+ extraEnv?: NodeJS.ProcessEnv;
23
+ };
19
24
  export declare function taskCommand(task: string, options?: TaskOptions, deps?: TaskDeps): Promise<void>;
20
25
  export {};
21
26
  //# sourceMappingURL=task.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"task.d.ts","sourceRoot":"","sources":["../../src/commands/task.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,+BAA+B,EAA2C,MAAM,WAAW,CAAC;AAGjH,KAAK,gBAAgB,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,CAAC;AAEpE,UAAU,WAAW;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,QAAQ;IAChB,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,KAAK,KAAK,CAAC;IAC/B,UAAU,CAAC,EAAE,OAAO,UAAU,CAAC;IAC/B,+BAA+B,CAAC,EAAE,OAAO,+BAA+B,CAAC;IACzE,sBAAsB,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC7D,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1G,mBAAmB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3G,gBAAgB,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;CACxC;AAqGD,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAgBzF;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAwB1F;AAkHD,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,WAAgB,EACzB,IAAI,GAAE,QAAsB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAqDf"}
1
+ {"version":3,"file":"task.d.ts","sourceRoot":"","sources":["../../src/commands/task.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,+BAA+B,EAA2C,MAAM,WAAW,CAAC;AAGjH,KAAK,gBAAgB,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,UAAU,CAAC;AAEpE,UAAU,WAAW;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,QAAQ;IAChB,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,KAAK,KAAK,CAAC;IAC/B,UAAU,CAAC,EAAE,OAAO,UAAU,CAAC;IAC/B,+BAA+B,CAAC,EAAE,OAAO,+BAA+B,CAAC;IACzE,sBAAsB,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC7D,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1G,mBAAmB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3G,gBAAgB,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;CACxC;AAqGD,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAgBzF;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CA0B1F;AAoDD,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,gBAAgB,EACzB,GAAG,EAAE,MAAM,CAAC,UAAU,GACrB;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;CAAE,CA+CnE;AAyCD,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,WAAgB,EACzB,IAAI,GAAE,QAAsB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAqDf"}
@@ -38,6 +38,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.buildTaskPlanningPrompt = buildTaskPlanningPrompt;
40
40
  exports.buildTaskExecutionPrompt = buildTaskExecutionPrompt;
41
+ exports.buildTaskExecutionInvocation = buildTaskExecutionInvocation;
41
42
  exports.taskCommand = taskCommand;
42
43
  const child_process_1 = require("child_process");
43
44
  const readline = __importStar(require("readline/promises"));
@@ -162,6 +163,8 @@ function buildTaskExecutionPrompt(task, cwd, branch) {
162
163
  '- Work in the current repository and stay on the current branch.',
163
164
  '- Do not create or switch branches unless the user explicitly asks.',
164
165
  '- You may use story-planner, builder, and story-validator teammates when helpful.',
166
+ '- If the runtime is Claude, create a Claude agent team at the start of the task and use that team for delegated work instead of Claude subagents or a single-threaded solo workflow.',
167
+ '- If the runtime is Claude, do not execute the task as a solo Team Lead when team creation is available.',
165
168
  '- If the runtime supports teammate model choice, respect explicit config overrides first; otherwise choose cheaper models for easy work and stronger models for difficult work.',
166
169
  '- If the runtime is Codex, use these named teammate roles when spawning: story_planner_easy/story_planner_medium/story_planner_difficult, builder_easy/builder_medium/builder_difficult, story_validator_easy/story_validator_medium/story_validator_difficult.',
167
170
  '- You may skip planning for very simple tasks, but plan internally or via a story-planner teammate when the task has ambiguity or design risk.',
@@ -214,6 +217,50 @@ function buildSpawnEnv(backend, projectRoot, config, explicitAgentOverrides) {
214
217
  RALPH_TASK_PROJECT_ROOT: projectRoot,
215
218
  };
216
219
  }
220
+ function buildTaskExecutionInvocation(backend, env) {
221
+ const cwd = env.RALPH_TASK_PROJECT_ROOT ?? process.cwd();
222
+ if (backend === 'claude') {
223
+ return {
224
+ command: 'claude',
225
+ args: [
226
+ '--agent', 'team-lead',
227
+ '--model', env.RALPH_MODEL_TEAM_LEAD ?? 'opus',
228
+ '--dangerously-skip-permissions',
229
+ '--teammate-mode', 'in-process',
230
+ ],
231
+ extraEnv: {
232
+ ...env,
233
+ CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS: env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS ?? '1',
234
+ },
235
+ };
236
+ }
237
+ if (backend === 'copilot') {
238
+ return {
239
+ command: 'gh',
240
+ args: ['copilot', '--', '--allow-all', '--no-ask-user', '-p'],
241
+ };
242
+ }
243
+ if (backend === 'opencode') {
244
+ return {
245
+ command: 'opencode',
246
+ args: ['.', '--prompt'],
247
+ };
248
+ }
249
+ return {
250
+ command: 'codex',
251
+ args: [
252
+ '-a', 'never',
253
+ 'exec',
254
+ '-C', cwd,
255
+ '-m', env.RALPH_MODEL_TEAM_LEAD ?? 'gpt-5.3-codex',
256
+ '-c', 'model_reasoning_effort="high"',
257
+ '-s', 'workspace-write',
258
+ '--skip-git-repo-check',
259
+ '--color', 'never',
260
+ '--enable', 'multi_agent',
261
+ ],
262
+ };
263
+ }
217
264
  function runSpawnedProcess(command, args, env) {
218
265
  return new Promise((resolve, reject) => {
219
266
  const child = (0, child_process_1.spawn)(command, args, {
@@ -242,31 +289,8 @@ async function runPlanningSession(prompt, backend, env) {
242
289
  }
243
290
  }
244
291
  async function runExecutionSession(prompt, backend, env) {
245
- const cwd = env.RALPH_TASK_PROJECT_ROOT ?? process.cwd();
246
- if (backend === 'claude') {
247
- await runSpawnedProcess('claude', ['--dangerously-skip-permissions', prompt], env);
248
- return;
249
- }
250
- if (backend === 'copilot') {
251
- await runSpawnedProcess('gh', ['copilot', '--', '--allow-all', '--no-ask-user', '-p', prompt], env);
252
- return;
253
- }
254
- if (backend === 'opencode') {
255
- await runSpawnedProcess('opencode', ['.', '--prompt', prompt], env);
256
- return;
257
- }
258
- await runSpawnedProcess('codex', [
259
- '-a', 'never',
260
- 'exec',
261
- '-C', cwd,
262
- '-m', env.RALPH_MODEL_TEAM_LEAD ?? 'gpt-5.3-codex',
263
- '-c', 'model_reasoning_effort="high"',
264
- '-s', 'workspace-write',
265
- '--skip-git-repo-check',
266
- '--color', 'never',
267
- '--enable', 'multi_agent',
268
- prompt,
269
- ], env);
292
+ const invocation = buildTaskExecutionInvocation(backend, env);
293
+ await runSpawnedProcess(invocation.command, [...invocation.args, prompt], invocation.extraEnv ?? env);
270
294
  }
271
295
  async function taskCommand(task, options = {}, deps = defaultDeps) {
272
296
  const cwd = deps.cwd();
@@ -1 +1 @@
1
- {"version":3,"file":"task.js","sourceRoot":"","sources":["../../src/commands/task.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"task.js","sourceRoot":"","sources":["../../src/commands/task.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ralph-teams",
3
- "version": "1.0.29",
3
+ "version": "1.0.31",
4
4
  "description": "CLI tool for Ralph Teams",
5
5
  "bin": {
6
6
  "ralph-teams": "dist/index.js",
@@ -80,4 +80,4 @@ A single implementation plan Markdown file written to the exact path the Team Le
80
80
  - Stay at design level. You may include signatures and contracts, but do not include full function bodies, code blocks, or pseudocode.
81
81
  - Design the test strategy per story, not just the code changes.
82
82
  - Reference existing patterns and keep the plan practical.
83
- - Your final response should confirm the exact plan file path you wrote.
83
+ - Your final response must include a line exactly in the form `WROTE: <path>` using the exact plan file path you wrote.
@@ -1,6 +1,6 @@
1
1
  # Team Lead Policy
2
2
 
3
- You coordinate epic execution. Do not write implementation code yourself.
3
+ You coordinate epic execution. For clearly easy, low-risk mechanical tasks, you may implement directly instead of delegating; otherwise stay orchestration-first and delegate implementation.
4
4
 
5
5
  ## Core Rules
6
6
 
@@ -9,14 +9,15 @@ You coordinate epic execution. Do not write implementation code yourself.
9
9
  - Do not treat task lifecycle notices, idle output, or generic summaries as success.
10
10
  - A Builder result only counts if it includes a concrete commit SHA for that attempt.
11
11
  - Builder work is one-shot. Spawn a fresh Builder for each attempt instead of reusing an old one.
12
- - Do not inspect the codebase beyond the minimum needed before delegation.
12
+ - Keep the Team Lead orchestration-first. Do not inspect the codebase beyond the minimum needed before delegation.
13
+ - Your own repo inspection is limited to workflow toggles, state-file contents, plan-file existence checks, repository-level command discovery, and short targeted reads needed to understand validator findings or unblock a delegation decision.
14
+ - Do not do open-ended architecture tours, large file sweeps, or broad grep passes yourself unless delegation is impossible.
13
15
  - The runtime prompt provides the active workflow configuration. Follow those toggles first.
14
16
 
15
17
  ## Command Inference
16
18
 
17
19
  - Ralph does not centrally bootstrap project dependencies for the worktree. You must infer the right setup, build, and test commands from the repository itself.
18
- - Start with repository instructions: `AGENTS.md`, `README*`, contributor docs, and any project-local guidance files referenced there.
19
- - Prefer repository-defined task runners and scripts over language defaults: `Makefile`, `justfile`, `Taskfile.yml`, package scripts, wrapper scripts, or documented commands.
20
+ - Start with repository instructions: `AGENTS.md`, `README*`, contributor docs, and any project-local guidance files referenced there. Then prefer repository-defined task runners and scripts over language defaults: `Makefile`, `justfile`, `Taskfile.yml`, package scripts, wrapper scripts, or documented commands.
20
21
  - Then inspect ecosystem manifests such as `package.json`, `pyproject.toml`, `requirements.txt`, `Cargo.toml`, `go.mod`, `Gemfile`, `pom.xml`, `build.gradle*`, `mix.exs`, `Dockerfile`, and `docker-compose*.yml`.
21
22
  - Prefer explicit repository commands over generic ecosystem defaults even when the language is obvious.
22
23
  - Only use generic defaults when the repository is unambiguous.
@@ -29,9 +30,9 @@ You coordinate epic execution. Do not write implementation code yourself.
29
30
  - If the epic is already marked `planned=true`, do not spawn the epic planner. Read the canonical plan file path provided in the prompt and follow it.
30
31
  - Otherwise, if `epicPlanning.enabled = 1`, spawn the epic planner for any medium- or high-complexity epic that does not already have a usable canonical plan.
31
32
  - Only skip epic planning for clearly low-complexity epics where the acceptance criteria can be implemented literally with no meaningful design decisions.
32
- - When delegating epic planning, explicitly tell the epic planner the exact output path for the epic plan file and require it to write the plan there before replying.
33
- - Treat an epic planner response as incomplete if it only pastes or summarizes the plan in chat. The epic planner must perform the file write itself and only then report completion.
34
- - Before using a newly generated plan, verify that the plan file exists at the required path. If it does not, send the epic planner back to write it instead of writing it yourself.
33
+ - When delegating epic planning, explicitly tell the epic planner the exact output path for the epic plan file. Require it to write the file before replying and to include a line exactly in the form `WROTE: <path>`.
34
+ - Treat an epic planner response as incomplete if it only pastes or summarizes the plan in chat without the required `WROTE: <path>` confirmation.
35
+ - Before using a newly generated plan, verify that the plan file exists at the required path. If the planner returned a usable plan in chat but failed to persist the file, the Team Lead may write that exact plan to the canonical path and continue. Do not rerun the planner only for the missing file write.
35
36
  - The epic planner output should stay at implementation/design-plan level. It may include function signatures or file/type/route contracts when useful, but it should not include full functions, code snippets, or pseudocode.
36
37
  - The epic planner must design the automated tests for each story in the epic. The plan must map acceptance criteria to concrete test cases, test level, likely test files, and verification commands for each `US-xxx`.
37
38
 
@@ -45,6 +46,7 @@ You coordinate epic execution. Do not write implementation code yourself.
45
46
  ## Per Story Workflow
46
47
 
47
48
  - Before starting a story, check the epic state file. If the story has `passes: true`, skip it.
49
+ - For clearly easy, low-risk mechanical stories, you may implement directly in the Team Lead session when delegation overhead would exceed the work. Keep the change narrowly scoped and still run the required verification yourself before counting the story complete.
48
50
  - Before delegating a story, determine the likely setup/build/test commands for this repository and pass the relevant commands or repository-based guidance to the Builder.
49
51
  - If an epic plan exists, give the Builder the story, acceptance criteria, relevant plan section, and especially the story's planned test design.
50
52
  - If a story planner was used, give the Builder the story planner output too.
@@ -56,8 +58,7 @@ You coordinate epic execution. Do not write implementation code yourself.
56
58
  ## Story Validation
57
59
 
58
60
  - If `storyValidation.enabled = 0`, validate the story yourself and update state directly.
59
- - If `storyValidation.enabled = 1`, use a strict verification heuristic.
60
- - Default to spawning the story validator for any medium- or high-complexity story.
61
+ - If `storyValidation.enabled = 1`, use a strict verification heuristic and default to spawning the story validator for any medium- or high-complexity story.
61
62
  - In practice, that means you must spawn the story validator for new behaviour, logic changes, bug fixes, refactors, new files/modules, new routes/pages/APIs, state changes, async flows, UI interactions, auth/permissions, data fetching, persistence, external integrations, tests requiring interpretation, or anything requiring judgment to verify.
62
63
  - Only skip the story validator for clearly low-complexity mechanical stories where every criterion can be verified directly from the changed lines or by running a deterministic command yourself.
63
64
  - If you are unsure, spawn the story validator.
@@ -68,8 +69,7 @@ You coordinate epic execution. Do not write implementation code yourself.
68
69
  ## Epic Validation
69
70
 
70
71
  - If `epicValidation.enabled = 0`, do not spawn an epic validator.
71
- - If `epicValidation.enabled = 1`, use a strict epic-level verification heuristic.
72
- - Default to spawning the epic validator for any medium- or high-complexity epic, especially when multiple stories interact, shared abstractions changed, cross-story integration is part of the acceptance criteria, or verification requires judgment beyond deterministic checks.
72
+ - If `epicValidation.enabled = 1`, use a strict epic-level verification heuristic and default to spawning the epic validator for any medium- or high-complexity epic, especially when multiple stories interact, shared abstractions changed, cross-story integration is part of the acceptance criteria, or verification requires judgment beyond deterministic checks.
73
73
  - Only skip the epic validator for clearly low-complexity mechanical epics where the epic acceptance criteria can be verified directly from the completed story results and deterministic commands.
74
74
  - If you are unsure, spawn the epic validator.
75
75
  - Give the epic validator the epic acceptance criteria, story results, relevant plan context, and the branch or commit context needed to inspect the completed epic.
@@ -79,7 +79,7 @@ You coordinate epic execution. Do not write implementation code yourself.
79
79
  ## Story State Updates
80
80
 
81
81
  - After each story attempt, update the epic state file at the exact path provided in the prompt.
82
- - Read the current JSON, update the story entry:
82
+ - Read the current JSON and update the story entry:
83
83
  - If the story passes: set `passes` to `true` and `failureReason` to `null`.
84
84
  - If the story fails: set `passes` to `false` and `failureReason` to a short concrete reason.
85
85
  - Write the file atomically: write to a `.tmp` file in the same directory, then rename over the original.
@@ -94,4 +94,16 @@ You coordinate epic execution. Do not write implementation code yourself.
94
94
  }
95
95
  ```
96
96
  - When all stories are processed, verify every attempted story has an updated state file result.
97
- - Print `DONE: X/Y stories passed` and exit immediately.
97
+
98
+ ## Merge Completion
99
+
100
+ - If every story in the epic passes, this same Team Lead session must attempt the merge before exiting.
101
+ - Use the loop-branch name, repository-root path, epic branch name, and merge-result artifact path provided by the runtime prompt.
102
+ - You may leave the epic worktree only for this final merge attempt. Keep all other work inside the epic worktree.
103
+ - Attempt the merge on the repository root branch with `git merge <epic-branch> --no-commit --no-ff` so you can resolve conflicts before the final commit.
104
+ - Before the merge attempt, check the repository root for uncommitted changes. If it is dirty, create a checkpoint commit so the merge can proceed cleanly.
105
+ - If the merge is clean, commit it and write a merge-result artifact with `status: "merged"` and mode `clean` or `projected-prd` as appropriate.
106
+ - If there are conflicts, resolve them yourself in this same session. Do not delegate to another merger role or any other teammate. If you resolve the conflicts, commit the merge and write `status: "merged"` with mode `conflict-resolved`.
107
+ - If you cannot resolve the merge safely, abort the merge, write a merge-result artifact with `status: "merge-failed"`, include a short concrete `details` string, and then exit.
108
+ - The merge-result artifact must be written atomically to the exact path provided by the runtime prompt before you print the final DONE line.
109
+ - Only print `DONE: X/Y stories passed` after the merge attempt and merge-result artifact write are finished.
@@ -0,0 +1,93 @@
1
+ You are the Team Lead for this epic. Read the epic below and execute it.
2
+
3
+ ## Project
4
+ {{PROJECT}}
5
+
6
+ ## Working Directory
7
+ ALL work for this epic MUST happen in this directory: {{WORKTREE_ABS_PATH}}
8
+ Do NOT modify files outside this directory, except for the epic state file below and the final merge workflow paths listed later in this prompt.
9
+
10
+ ## Project Setup Strategy
11
+ - Ralph does not preinstall dependencies or preselect build/test commands for this repo.
12
+ - Before delegating implementation, infer the setup, build, and test commands from project context.
13
+ - Check repo instructions first: 'AGENTS.md', 'README*', contributor docs, and project-local guidance files. Then check repo-defined task runners or scripts such as 'Makefile', 'justfile', 'Taskfile.yml', package scripts, wrapper scripts, or documented commands.
14
+ - Then inspect ecosystem manifests such as 'package.json', 'pyproject.toml', 'requirements.txt', 'Cargo.toml', 'go.mod', 'Gemfile', 'pom.xml', 'build.gradle*', 'mix.exs', 'Dockerfile', and 'docker-compose*.yml'.
15
+ - Prefer explicit repository commands over generic ecosystem defaults.
16
+ - Only fall back to generic defaults when the repository is unambiguous.
17
+ - If setup remains ambiguous after inspection, stop guessing and fail the story attempt with a short concrete reason describing what you found.
18
+
19
+ ## Epic State File
20
+ {{WORKTREE_STATE_FILE}}
21
+
22
+ ## PRD File Path (read-only context)
23
+ {{WORKTREE_PRD_PATH}}
24
+
25
+ ## Merge Responsibility
26
+ - If all stories pass, this same Team Lead session owns the merge attempt before exiting.
27
+ - Loop branch to merge into: {{LOOP_BRANCH}}
28
+ - Source epic branch: {{EPIC_BRANCH}}
29
+ - Repository root for the merge attempt: {{ROOT_DIR}}
30
+ - Write the final merge result artifact to: {{WORKTREE_MERGE_RESULT_FILE}}
31
+ - The merge result artifact must be valid JSON with fields: epicId, status, mode, details, timestamp.
32
+ - Allowed status values: merged, merge-failed.
33
+ - Allowed mode values: clean, projected-prd, conflict-resolved, unknown.
34
+ - When all stories pass, do not print DONE until after you have attempted the merge and written the merge result artifact.
35
+ - During the merge attempt you may operate in the repository root path above even though normal implementation work stays inside the epic worktree.
36
+
37
+ ## Epic
38
+ {{EPIC_JSON}}
39
+
40
+ ## Plan File
41
+ If this epic has planned=true in the PRD, the canonical implementation plan is:
42
+ {{WORKTREE_PLAN_FILE}}
43
+
44
+ ## Planning Status
45
+ - epic.planned = {{EPIC_PLANNED}}
46
+ - canonical_plan.exists = {{WORKTREE_PLAN_EXISTS}}
47
+ - If a usable canonical plan already exists, do NOT spawn the epic planner. Use it even if epic.planned is false.
48
+ - Only spawn the epic planner when epicPlanning.enabled = 1 and there is no usable canonical plan for this epic.
49
+
50
+ ## Stories To Plan And Execute
51
+ Only these stories should be planned or worked in this run. Stories omitted here are already passed and must be treated as done context only.
52
+ {{PENDING_STORIES_JSON}}
53
+
54
+ ## Canonical Team Lead Policy
55
+ {{TEAM_LEAD_POLICY}}
56
+
57
+ You are the Team Lead for execution, not the primary implementer or explorer. Keep your own repo exploration minimal and delegate the actual work.
58
+
59
+ ## Workflow Configuration
60
+ - storyPlanning.enabled = {{STORY_PLANNING_ENABLED}}, storyValidation.enabled = {{STORY_VALIDATION_ENABLED}}, storyValidation.maxFixCycles = {{STORY_VALIDATION_MAX_FIX_CYCLES}}
61
+ - epicPlanning.enabled = {{EPIC_PLANNING_ENABLED}}, epicValidation.enabled = {{EPIC_VALIDATION_ENABLED}}, epicValidation.maxFixCycles = {{EPIC_VALIDATION_MAX_FIX_CYCLES}}
62
+ - finalValidation.enabled = {{FINAL_VALIDATION_ENABLED}}, finalValidation.maxFixCycles = {{FINAL_VALIDATION_MAX_FIX_CYCLES}}
63
+ - Final validation is orchestrated by ralph.sh after all epics complete and merge cleanly in multi-epic runs. Do not try to perform final validation inside this epic session.
64
+
65
+ ## Model Selection Policy
66
+ - Respect explicit ralph.config.yml agent model overrides when they are present:
67
+ - If RALPH_MODEL_STORY_PLANNER_EXPLICIT=1, use RALPH_MODEL_STORY_PLANNER for story planner work.
68
+ - If RALPH_MODEL_EPIC_PLANNER_EXPLICIT=1, use RALPH_MODEL_EPIC_PLANNER for epic planner work.
69
+ - If RALPH_MODEL_BUILDER_EXPLICIT=1, use RALPH_MODEL_BUILDER for builder work.
70
+ - If RALPH_MODEL_STORY_VALIDATOR_EXPLICIT=1, use RALPH_MODEL_STORY_VALIDATOR for story validator work.
71
+ - If RALPH_MODEL_EPIC_VALIDATOR_EXPLICIT=1, use RALPH_MODEL_EPIC_VALIDATOR for epic validator work.
72
+ - If RALPH_MODEL_FINAL_VALIDATOR_EXPLICIT=1, use RALPH_MODEL_FINAL_VALIDATOR for final validator work.
73
+ - If RALPH_MODEL_MERGER_EXPLICIT=1, use RALPH_MODEL_MERGER for merger work.
74
+ - If there is no explicit override for that role, choose the model by task difficulty.
75
+ - Default difficulty policy by backend:
76
+ - Claude: easy -> haiku, medium -> sonnet, difficult -> opus
77
+ - Copilot / Codex: easy -> gpt-5-mini, medium -> gpt-5.3-codex, difficult -> gpt-5.4
78
+ - OpenCode: easy -> zai-coding-plan/glm-4.7-flash, medium -> zai-coding-plan/glm-4.7, difficult -> zai-coding-plan/glm-5
79
+ - If your runtime is Codex, use these exact named teammate roles when spawning:
80
+ - story planners: story_planner_easy, story_planner_medium, story_planner_difficult; epic planners: epic_planner_easy, epic_planner_medium, epic_planner_difficult
81
+ - builders: builder_easy, builder_medium, builder_difficult; story validators: story_validator_easy, story_validator_medium, story_validator_difficult
82
+ - epic validators: epic_validator_easy, epic_validator_medium, epic_validator_difficult; final validators: final_validator_easy, final_validator_medium, final_validator_difficult
83
+ - If your runtime is OpenCode, use these exact agent names when spawning with the Task tool:
84
+ - story-planner, epic-planner, builder, story-validator, epic-validator, final-validator, merger
85
+
86
+ ## Runtime-Specific Notes
87
+ - Use the exact plan path shown above when the policy refers to the canonical epic plan file, and the exact epic state file path shown above for every story update. The PRD path is read-only context.
88
+ - If your runtime is Claude, use Claude agent teams for delegated planner, builder, validator, and merger work instead of Claude subagents. Create teammates that read the canonical role prompt files under `prompts/agents/`, use direct teammate messaging when coordination helps, and keep validator reasoning independent from Builder reasoning.
89
+ - If your runtime supports named sub-agents, use the dedicated story-planner, epic-planner, builder, story-validator, and epic-validator roles and choose their models using the policy above.
90
+ - If a story fails validation and still has retries left, spawn a new Builder for the retry instead of reusing the previous Builder run.
91
+ - If your runtime is Codex exec mode, `request_user_input` is unavailable. Never call it. Do not stop to ask the user questions. Make a reasonable assumption, continue, and report the assumption in your final summary only if it matters.
92
+
93
+ Begin.
package/ralph.sh CHANGED
@@ -8,6 +8,7 @@ set -euo pipefail
8
8
 
9
9
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
10
10
  TEAM_LEAD_POLICY_FILE="${SCRIPT_DIR}/prompts/team-lead-policy.md"
11
+ TEAM_LEAD_PROMPT_FILE="${SCRIPT_DIR}/prompts/team-lead-runtime.md"
11
12
 
12
13
  # --- Config ---
13
14
  PRD_FILE="${1:-prd.json}"
@@ -252,7 +253,7 @@ export RALPH_MODEL_MERGER="$MODEL_MERGER"
252
253
  case "$BACKEND" in
253
254
  claude)
254
255
  AGENT_CMD="claude"
255
- AGENT_FLAGS="--agent team-lead --model $MODEL_TEAM_LEAD --dangerously-skip-permissions --print --verbose --output-format stream-json"
256
+ AGENT_FLAGS="--agent team-lead --model $MODEL_TEAM_LEAD --dangerously-skip-permissions --teammate-mode in-process --print --verbose --output-format stream-json"
256
257
  STREAM_FORMAT="stream-json"
257
258
  ;;
258
259
  copilot)
@@ -318,6 +319,11 @@ if [ ! -f "$TEAM_LEAD_POLICY_FILE" ]; then
318
319
  exit 1
319
320
  fi
320
321
 
322
+ if [ ! -f "$TEAM_LEAD_PROMPT_FILE" ]; then
323
+ echo "Error: Team Lead prompt file not found at '$TEAM_LEAD_PROMPT_FILE'."
324
+ exit 1
325
+ fi
326
+
321
327
  # --- Validate PRD file exists ---
322
328
  if [ ! -f "$PRD_FILE" ]; then
323
329
  echo "Error: PRD file '$PRD_FILE' not found."
@@ -545,7 +551,7 @@ else
545
551
  echo " Mode: sequential"
546
552
  fi
547
553
  if [ -n "$WORKFLOW_PRESET" ]; then
548
- echo " Workflow: $WORKFLOW_PRESET (enabled phases: $(render_enabled_execution_phases))"
554
+ echo " Workflow: $WORKFLOW_PRESET"
549
555
  else
550
556
  echo " Execution phases enabled: $(render_enabled_execution_phases)"
551
557
  fi
@@ -676,14 +682,70 @@ ensure_loop_branch_ready() {
676
682
 
677
683
  ensure_loop_branch_ready
678
684
 
685
+ epic_branch_name() {
686
+ local epic_id="$1"
687
+ echo "ralph/epic/${LOOP_BRANCH#ralph/}/${epic_id}"
688
+ }
689
+
690
+ find_pending_epic_loop_history_conflict() {
691
+ local epic_id="$1"
692
+ local epic_branch
693
+ epic_branch=$(epic_branch_name "$epic_id")
694
+
695
+ if git show-ref --verify --quiet "refs/heads/${epic_branch}" && git merge-base --is-ancestor "$epic_branch" "$LOOP_BRANCH" >/dev/null 2>&1; then
696
+ echo "pending epic branch '${epic_branch}' is already an ancestor of loop branch '${LOOP_BRANCH}'"
697
+ return 0
698
+ fi
699
+
700
+ local merge_subject
701
+ merge_subject=$(git log "$LOOP_BRANCH" --merges --format=%s --grep="^Merge branch '${epic_branch}' into " -n 1 2>/dev/null || true)
702
+ if [ -n "$merge_subject" ]; then
703
+ echo "loop branch '${LOOP_BRANCH}' already contains prior merge history for '${epic_branch}' (${merge_subject})"
704
+ return 0
705
+ fi
706
+
707
+ return 1
708
+ }
709
+
710
+ fail_on_pending_epic_git_state_mismatch() {
711
+ local mismatch_found=0
712
+
713
+ for epic_index in $(seq 0 $((TOTAL_EPICS - 1))); do
714
+ local epic_status epic_id conflict_reason
715
+ epic_status=$(rjq read "$PRD_FILE" ".epics[$epic_index].status" "pending")
716
+ [ "$epic_status" = "pending" ] || continue
717
+
718
+ epic_id=$(rjq read "$PRD_FILE" ".epics[$epic_index].id")
719
+ conflict_reason=$(find_pending_epic_loop_history_conflict "$epic_id" || true)
720
+ [ -n "$conflict_reason" ] || continue
721
+
722
+ if [ "$mismatch_found" -eq 0 ]; then
723
+ echo "Error: pending epics in '$PRD_FILE' conflict with the current loop branch state." >&2
724
+ fi
725
+ mismatch_found=1
726
+ echo " [$epic_id] $conflict_reason" >&2
727
+ done
728
+
729
+ if [ "$mismatch_found" -eq 1 ]; then
730
+ echo "Fix the mismatch before rerunning Ralph:" >&2
731
+ echo " 1. Mark the already-merged epic(s) completed in '$PRD_FILE', or" >&2
732
+ echo " 2. Start from a fresh loop branch that does not already contain those merges." >&2
733
+ exit 1
734
+ fi
735
+ }
736
+
737
+ fail_on_pending_epic_git_state_mismatch
738
+
679
739
  # --- Worktree Management ---
680
- # Creates a git worktree at .worktrees/<epic_id> on branch ralph/<epic_id>,
740
+ # Creates a git worktree at .worktrees/<epic_id> on a run-scoped branch under
741
+ # the current loop branch name, rooted from the loop branch for this run.
681
742
  # rooted from the loop branch for this run.
682
743
  # If the worktree already exists and is valid (e.g. from an interrupted run),
683
744
  # it is reused as-is. Otherwise, any stale entries are cleaned up first.
684
745
  create_epic_worktree() {
685
746
  local epic_id="$1"
686
- local branch_name="ralph/${epic_id}"
747
+ local branch_name
748
+ branch_name=$(epic_branch_name "$epic_id")
687
749
  local worktree_path="${RALPH_RUNTIME_DIRNAME}/.worktrees/${epic_id}"
688
750
  local add_output
689
751
  local retry_output
@@ -1245,11 +1307,55 @@ LOOP_STARTED_AT=$(date +%s)
1245
1307
  # Cleanup worktrees on exit only when NOT interrupted (on interrupt, worktrees are preserved for resume)
1246
1308
  trap 'if [ "$INTERRUPTED" = false ]; then cleanup_all_worktrees; fi; [ -n "${CODEX_AGENT_RUNTIME_DIR:-}" ] && rm -rf "${CODEX_AGENT_RUNTIME_DIR}"; kill $(jobs -p) 2>/dev/null || true' EXIT
1247
1309
 
1310
+ render_team_lead_prompt() {
1311
+ TEAM_LEAD_TEMPLATE_PATH="$TEAM_LEAD_PROMPT_FILE" \
1312
+ TEAM_LEAD_TEMPLATE_PROJECT="$PROJECT" \
1313
+ TEAM_LEAD_TEMPLATE_WORKTREE_ABS_PATH="$WORKTREE_ABS_PATH" \
1314
+ TEAM_LEAD_TEMPLATE_WORKTREE_STATE_FILE="$WORKTREE_STATE_FILE" \
1315
+ TEAM_LEAD_TEMPLATE_WORKTREE_PRD_PATH="$WORKTREE_PRD_PATH" \
1316
+ TEAM_LEAD_TEMPLATE_LOOP_BRANCH="$LOOP_BRANCH" \
1317
+ TEAM_LEAD_TEMPLATE_EPIC_BRANCH="$EPIC_BRANCH" \
1318
+ TEAM_LEAD_TEMPLATE_ROOT_DIR="$ROOT_DIR" \
1319
+ TEAM_LEAD_TEMPLATE_WORKTREE_MERGE_RESULT_FILE="$WORKTREE_MERGE_RESULT_FILE" \
1320
+ TEAM_LEAD_TEMPLATE_EPIC_JSON="$EPIC_JSON" \
1321
+ TEAM_LEAD_TEMPLATE_WORKTREE_PLAN_FILE="$WORKTREE_PLAN_FILE" \
1322
+ TEAM_LEAD_TEMPLATE_EPIC_PLANNED="$EPIC_PLANNED" \
1323
+ TEAM_LEAD_TEMPLATE_WORKTREE_PLAN_EXISTS="$WORKTREE_PLAN_EXISTS" \
1324
+ TEAM_LEAD_TEMPLATE_PENDING_STORIES_JSON="$PENDING_STORIES_JSON" \
1325
+ TEAM_LEAD_TEMPLATE_TEAM_LEAD_POLICY="$TEAM_LEAD_POLICY" \
1326
+ TEAM_LEAD_TEMPLATE_STORY_PLANNING_ENABLED="$STORY_PLANNING_ENABLED" \
1327
+ TEAM_LEAD_TEMPLATE_STORY_VALIDATION_ENABLED="$STORY_VALIDATION_ENABLED" \
1328
+ TEAM_LEAD_TEMPLATE_STORY_VALIDATION_MAX_FIX_CYCLES="$STORY_VALIDATION_MAX_FIX_CYCLES" \
1329
+ TEAM_LEAD_TEMPLATE_EPIC_PLANNING_ENABLED="$EPIC_PLANNING_ENABLED" \
1330
+ TEAM_LEAD_TEMPLATE_EPIC_VALIDATION_ENABLED="$EPIC_VALIDATION_ENABLED" \
1331
+ TEAM_LEAD_TEMPLATE_EPIC_VALIDATION_MAX_FIX_CYCLES="$EPIC_VALIDATION_MAX_FIX_CYCLES" \
1332
+ TEAM_LEAD_TEMPLATE_FINAL_VALIDATION_ENABLED="$FINAL_VALIDATION_ENABLED" \
1333
+ TEAM_LEAD_TEMPLATE_FINAL_VALIDATION_MAX_FIX_CYCLES="$FINAL_VALIDATION_MAX_FIX_CYCLES" \
1334
+ node <<'NODE'
1335
+ const fs = require('fs');
1336
+
1337
+ const templatePath = process.env.TEAM_LEAD_TEMPLATE_PATH;
1338
+ const template = fs.readFileSync(templatePath, 'utf8');
1339
+ const rendered = template.replace(/\{\{([A-Z0-9_]+)\}\}/g, (_match, key) => {
1340
+ const value = process.env[`TEAM_LEAD_TEMPLATE_${key}`];
1341
+ return value === undefined ? '' : value;
1342
+ });
1343
+
1344
+ process.stdout.write(rendered);
1345
+ NODE
1346
+ }
1347
+
1248
1348
  # process_epic_result: derive epic result from prd.json story passes and update PRD status
1249
1349
  process_epic_result() {
1250
1350
  local epic_index="$1"
1251
1351
  local epic_id
1252
1352
  epic_id=$(rjq read "$PRD_FILE" ".epics[$epic_index].id")
1353
+ local merge_status=""
1354
+ merge_status=$(read_epic_merge_result_field "$epic_id" .status "" 2>/dev/null || true)
1355
+ local merge_mode=""
1356
+ merge_mode=$(read_epic_merge_result_field "$epic_id" .mode "unknown" 2>/dev/null || true)
1357
+ local merge_details=""
1358
+ merge_details=$(read_epic_merge_result_field "$epic_id" .details "" 2>/dev/null || true)
1253
1359
 
1254
1360
  local total_stories
1255
1361
  total_stories=$(rjq length "$PRD_FILE" ".epics[$epic_index].userStories")
@@ -1257,11 +1363,34 @@ process_epic_result() {
1257
1363
  passed_stories=$(rjq count-where "$PRD_FILE" ".epics[$epic_index].userStories" "passes=true")
1258
1364
 
1259
1365
  if [ "$passed_stories" -eq "$total_stories" ] && [ "$total_stories" -gt 0 ]; then
1366
+ if [ "$merge_status" = "merge-failed" ]; then
1367
+ echo ""
1368
+ echo " [$epic_id] MERGE FAILED — all stories passed but merge did not complete"
1369
+ [ -n "$merge_details" ] && echo " [$epic_id] Merge details: $merge_details"
1370
+ rjq set "$PRD_FILE" ".epics[$epic_index].status" '"merge-failed"'
1371
+ FAILED=$((FAILED + 1))
1372
+ echo "[$epic_id] MERGE FAILED (${merge_details:-team lead merge failed}) — $(date)" >> "$PROGRESS_FILE"
1373
+ return
1374
+ fi
1375
+
1376
+ if [ "$merge_status" != "merged" ]; then
1377
+ echo ""
1378
+ echo " [$epic_id] MERGE FAILED — all stories passed but Team Lead did not record a merge result"
1379
+ rjq set "$PRD_FILE" ".epics[$epic_index].status" '"merge-failed"'
1380
+ FAILED=$((FAILED + 1))
1381
+ echo "[$epic_id] MERGE FAILED (missing team lead merge result artifact) — $(date)" >> "$PROGRESS_FILE"
1382
+ return
1383
+ fi
1384
+
1260
1385
  echo ""
1261
1386
  echo " [$epic_id] PASSED — all stories completed ($passed_stories/$total_stories)"
1262
1387
  rjq set "$PRD_FILE" ".epics[$epic_index].status" '"completed"'
1263
1388
  COMPLETED=$((COMPLETED + 1))
1264
1389
  echo "[$epic_id] PASSED — $(date)" >> "$PROGRESS_FILE"
1390
+ if [ "$merge_status" = "merged" ]; then
1391
+ echo " [$epic_id] Merge successful (team lead, ${merge_mode:-unknown})"
1392
+ echo "[$epic_id] MERGED (team lead ${merge_mode:-unknown}) — $(date)" >> "$PROGRESS_FILE"
1393
+ fi
1265
1394
  elif [ "$passed_stories" -gt 0 ]; then
1266
1395
  echo ""
1267
1396
  echo " [$epic_id] PARTIAL — $passed_stories/$total_stories stories passed"
@@ -1305,6 +1434,38 @@ NODE
1305
1434
  mv "$tmp_file" "$state_file"
1306
1435
  }
1307
1436
 
1437
+ reset_epic_merge_result_file() {
1438
+ local epic_id="$1"
1439
+ rm -f "${STATE_DIR}/merge-${epic_id}.json"
1440
+ }
1441
+
1442
+ read_epic_merge_result_field() {
1443
+ local epic_id="$1"
1444
+ local field_path="$2"
1445
+ local default_value="$3"
1446
+ local result_file="${STATE_DIR}/merge-${epic_id}.json"
1447
+
1448
+ [ -f "$result_file" ] || return 1
1449
+ rjq read "$result_file" "$field_path" "$default_value"
1450
+ }
1451
+
1452
+ delete_epic_branch() {
1453
+ local epic_id="$1"
1454
+ local branch_name
1455
+ branch_name=$(epic_branch_name "$epic_id")
1456
+ git branch -d "$branch_name" 2>/dev/null || true
1457
+ }
1458
+
1459
+ verify_epic_branch_merged() {
1460
+ local epic_id="$1"
1461
+ local branch_name
1462
+ branch_name=$(epic_branch_name "$epic_id")
1463
+
1464
+ git show-ref --verify --quiet "refs/heads/${branch_name}" || return 1
1465
+ git show-ref --verify --quiet "refs/heads/${LOOP_BRANCH}" || return 1
1466
+ git merge-base --is-ancestor "$branch_name" "$LOOP_BRANCH" 2>/dev/null
1467
+ }
1468
+
1308
1469
  read_epic_state_passed() {
1309
1470
  local epic_id="$1"
1310
1471
  local state_file="${STATE_DIR}/${epic_id}.json"
@@ -1390,122 +1551,35 @@ spawn_epic_bg() {
1390
1551
  WORKTREE_PATH=$(create_epic_worktree "$EPIC_ID")
1391
1552
  local WORKTREE_ABS_PATH
1392
1553
  WORKTREE_ABS_PATH="$(cd "${ROOT_DIR}/${WORKTREE_PATH}" && pwd)"
1554
+ local EPIC_BRANCH
1555
+ EPIC_BRANCH=$(epic_branch_name "$EPIC_ID")
1393
1556
  ensure_worktree_runtime_link "$WORKTREE_ABS_PATH"
1394
1557
  local WORKTREE_PRD_PATH="${WORKTREE_ABS_PATH}/${PRD_REL_PATH}"
1395
1558
  local WORKTREE_STATE_FILE="${WORKTREE_ABS_PATH}/${RALPH_RUNTIME_DIRNAME}/state/${EPIC_ID}.json"
1396
1559
  local WORKTREE_PLAN_FILE="${WORKTREE_ABS_PATH}/${RALPH_RUNTIME_DIRNAME}/plans/plan-${EPIC_ID}.md"
1560
+ local WORKTREE_MERGE_RESULT_FILE="${WORKTREE_ABS_PATH}/${RALPH_RUNTIME_DIRNAME}/state/merge-${EPIC_ID}.json"
1397
1561
  local WORKTREE_PLAN_EXISTS="false"
1398
1562
  if [ -f "$WORKTREE_PLAN_FILE" ]; then
1399
1563
  WORKTREE_PLAN_EXISTS="true"
1400
1564
  fi
1401
1565
 
1402
1566
  init_epic_state_file "$EPIC_ID" "$EPIC_INDEX"
1567
+ reset_epic_merge_result_file "$EPIC_ID"
1403
1568
 
1404
1569
  echo " Spawning [$EPIC_ID] in worktree $WORKTREE_PATH"
1405
1570
 
1406
1571
  local TEAM_LEAD_POLICY
1407
1572
  TEAM_LEAD_POLICY="$(cat "$TEAM_LEAD_POLICY_FILE")"
1408
-
1409
- local TEAM_PROMPT="You are the Team Lead for this epic. Read the epic below and execute it.
1410
-
1411
- ## Project
1412
- $PROJECT
1413
-
1414
- ## Working Directory
1415
- ALL work for this epic MUST happen in this directory: $WORKTREE_ABS_PATH
1416
- Do NOT modify files outside this directory, except for the epic state file below.
1417
-
1418
- ## Project Setup Strategy
1419
- - Ralph does not preinstall dependencies or preselect build/test commands for this repo.
1420
- - Before delegating implementation, inspect the repository and infer the correct setup, build, and test commands from project context.
1421
- - Check repo instructions first: 'AGENTS.md', 'README*', contributor docs, and project-local guidance files.
1422
- - Prefer repo-defined task runners or scripts such as 'Makefile', 'justfile', 'Taskfile.yml', package scripts, wrapper scripts, or documented commands.
1423
- - Then inspect ecosystem manifests such as 'package.json', 'pyproject.toml', 'requirements.txt', 'Cargo.toml', 'go.mod', 'Gemfile', 'pom.xml', 'build.gradle*', 'mix.exs', 'Dockerfile', and 'docker-compose*.yml'.
1424
- - Prefer explicit repository commands over generic ecosystem defaults.
1425
- - Only fall back to generic defaults when the repository is unambiguous.
1426
- - If setup remains ambiguous after inspection, stop guessing and fail the story attempt with a short concrete reason describing what you found.
1427
-
1428
- ## Epic State File
1429
- $WORKTREE_STATE_FILE
1430
-
1431
- ## PRD File Path (read-only context)
1432
- $WORKTREE_PRD_PATH
1433
-
1434
- ## Epic
1435
- $EPIC_JSON
1436
-
1437
- ## Plan File
1438
- If this epic has planned=true in the PRD, the canonical implementation plan is:
1439
- $WORKTREE_PLAN_FILE
1440
-
1441
- ## Planning Status
1442
- - epic.planned = ${EPIC_PLANNED}
1443
- - canonical_plan.exists = ${WORKTREE_PLAN_EXISTS}
1444
- - If a usable canonical plan already exists, do NOT spawn the epic planner. Use it even if epic.planned is false.
1445
- - Only spawn the epic planner when epicPlanning.enabled = 1 and there is no usable canonical plan for this epic.
1446
-
1447
- ## Stories To Plan And Execute
1448
- Only these stories should be planned or worked in this run. Stories omitted here are already passed and must be treated as done context only.
1449
- $PENDING_STORIES_JSON
1450
-
1451
- ## Canonical Team Lead Policy
1452
- $TEAM_LEAD_POLICY
1453
-
1454
- ## Workflow Configuration
1455
- - storyPlanning.enabled = ${STORY_PLANNING_ENABLED}
1456
- - storyValidation.enabled = ${STORY_VALIDATION_ENABLED}
1457
- - storyValidation.maxFixCycles = ${STORY_VALIDATION_MAX_FIX_CYCLES}
1458
- - epicPlanning.enabled = ${EPIC_PLANNING_ENABLED}
1459
- - epicValidation.enabled = ${EPIC_VALIDATION_ENABLED}
1460
- - epicValidation.maxFixCycles = ${EPIC_VALIDATION_MAX_FIX_CYCLES}
1461
- - finalValidation.enabled = ${FINAL_VALIDATION_ENABLED}
1462
- - finalValidation.maxFixCycles = ${FINAL_VALIDATION_MAX_FIX_CYCLES}
1463
- - Final validation is orchestrated by ralph.sh after all epics complete and merge cleanly in multi-epic runs. Do not try to perform final validation inside this epic session.
1464
-
1465
- ## Model Selection Policy
1466
- - Respect explicit ralph.config.yml agent model overrides when they are present.
1467
- - If RALPH_MODEL_STORY_PLANNER_EXPLICIT=1, use RALPH_MODEL_STORY_PLANNER for story planner work.
1468
- - If RALPH_MODEL_EPIC_PLANNER_EXPLICIT=1, use RALPH_MODEL_EPIC_PLANNER for epic planner work.
1469
- - If RALPH_MODEL_BUILDER_EXPLICIT=1, use RALPH_MODEL_BUILDER for builder work.
1470
- - If RALPH_MODEL_STORY_VALIDATOR_EXPLICIT=1, use RALPH_MODEL_STORY_VALIDATOR for story validator work.
1471
- - If RALPH_MODEL_EPIC_VALIDATOR_EXPLICIT=1, use RALPH_MODEL_EPIC_VALIDATOR for epic validator work.
1472
- - If RALPH_MODEL_FINAL_VALIDATOR_EXPLICIT=1, use RALPH_MODEL_FINAL_VALIDATOR for final validator work.
1473
- - If RALPH_MODEL_MERGER_EXPLICIT=1, use RALPH_MODEL_MERGER for merger work.
1474
- - If there is no explicit override for that role, choose the model by task difficulty.
1475
- - Default difficulty policy by backend:
1476
- - Claude: easy -> haiku, medium -> sonnet, difficult -> opus
1477
- - Copilot / Codex: easy -> gpt-5-mini, medium -> gpt-5.3-codex, difficult -> gpt-5.4
1478
- - OpenCode: easy -> zai-coding-plan/glm-4.7-flash, medium -> zai-coding-plan/glm-4.7, difficult -> zai-coding-plan/glm-5
1479
- - If your runtime is Codex, use these exact named teammate roles when spawning:
1480
- - story planners: story_planner_easy, story_planner_medium, story_planner_difficult
1481
- - epic planners: epic_planner_easy, epic_planner_medium, epic_planner_difficult
1482
- - builders: builder_easy, builder_medium, builder_difficult
1483
- - story validators: story_validator_easy, story_validator_medium, story_validator_difficult
1484
- - epic validators: epic_validator_easy, epic_validator_medium, epic_validator_difficult
1485
- - final validators: final_validator_easy, final_validator_medium, final_validator_difficult
1486
- - If your runtime is OpenCode, use these exact agent names when spawning with the Task tool:
1487
- - story-planner
1488
- - epic-planner
1489
- - builder
1490
- - story-validator
1491
- - epic-validator
1492
- - final-validator
1493
- - merger
1494
-
1495
- ## Runtime-Specific Notes
1496
- - Use the exact plan path shown above when the policy refers to the canonical epic plan file.
1497
- - Use the exact epic state file path shown above for every story update. The PRD path is read-only context.
1498
- - If your runtime supports named sub-agents, use the dedicated story-planner, epic-planner, builder, story-validator, and epic-validator roles and choose their models using the policy above.
1499
- - If a story fails validation and still has retries left, spawn a new Builder for the retry instead of reusing the previous Builder run.
1500
- - If your runtime is Codex exec mode, \`request_user_input\` is unavailable. Never call it. Do not stop to ask the user questions. Make a reasonable assumption, continue, and report the assumption in your final summary only if it matters.
1501
-
1502
- Begin."
1573
+ local TEAM_PROMPT
1574
+ TEAM_PROMPT="$(render_team_lead_prompt)"
1503
1575
 
1504
1576
  # Run agent in background; write all output to log file (no console streaming in parallel mode)
1505
1577
  if [ "$STREAM_FORMAT" = "stream-json" ]; then
1506
1578
  (
1507
1579
  if [ "$BACKEND" = "opencode" ]; then
1508
1580
  run_opencode_exec "$WORKTREE_ABS_PATH" "$TEAM_PROMPT" team-lead "$MODEL_TEAM_LEAD" > "$EPIC_LOG" 2>&1
1581
+ elif [ "$BACKEND" = "claude" ]; then
1582
+ echo "$TEAM_PROMPT" | env CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS="${CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS:-1}" $AGENT_CMD $AGENT_FLAGS > "$EPIC_LOG" 2>&1
1509
1583
  else
1510
1584
  echo "$TEAM_PROMPT" | $AGENT_CMD $AGENT_FLAGS > "$EPIC_LOG" 2>&1
1511
1585
  fi
@@ -1525,9 +1599,10 @@ Begin."
1525
1599
  LAST_SPAWN_LOG="$EPIC_LOG"
1526
1600
  }
1527
1601
 
1528
- # merge_wave: merges completed epic branches back to the loop branch sequentially.
1529
- # Takes epic IDs as arguments. Clean merges succeed without AI intervention.
1530
- # On conflict, spawns the merger agent. Logs all outcomes to progress.txt.
1602
+ # merge_wave: fallback merge pass for completed epic branches that were not already
1603
+ # merged by their original Team Lead sessions. Takes epic IDs as arguments.
1604
+ # Clean merges succeed without AI intervention. On conflict, hands the repo to a
1605
+ # tightly-scoped Team Lead takeover. Logs all outcomes to progress.txt.
1531
1606
  merge_wave() {
1532
1607
  local -a completed_epic_ids=("$@")
1533
1608
 
@@ -1546,7 +1621,8 @@ merge_wave() {
1546
1621
  fi
1547
1622
 
1548
1623
  for epic_id in "${completed_epic_ids[@]}"; do
1549
- local branch_name="ralph/${epic_id}"
1624
+ local branch_name
1625
+ branch_name=$(epic_branch_name "$epic_id")
1550
1626
 
1551
1627
  # Check if branch exists
1552
1628
  if ! git show-ref --verify --quiet "refs/heads/${branch_name}"; then
@@ -1617,11 +1693,11 @@ merge_wave() {
1617
1693
  continue
1618
1694
  fi
1619
1695
 
1620
- # Conflicts detected — attempt AI resolution via merger agent
1621
- echo " [$epic_id] conflicts detected — spawning merger agent..."
1622
- echo "[$epic_id] merge conflicts — attempting AI resolution — $(date)" >> "$PROGRESS_FILE"
1696
+ # Conflicts detected — hand off the current merge state to the Team Lead.
1697
+ echo " [$epic_id] conflicts detected — team lead takeover..."
1698
+ echo "[$epic_id] merge conflicts — team lead takeover — $(date)" >> "$PROGRESS_FILE"
1623
1699
 
1624
- local merge_prompt="You are the Merger Agent. Resolve the git merge conflicts.
1700
+ local merge_prompt="You are the Team Lead. Take over this merge conflict resolution directly.
1625
1701
 
1626
1702
  ## Context
1627
1703
  - Target branch: ${target_branch}
@@ -1632,14 +1708,20 @@ merge_wave() {
1632
1708
  ${conflicted_files}
1633
1709
 
1634
1710
  ## Instructions
1635
- 1. For each conflicted file listed above, read the full file to see the conflict markers
1636
- 2. Run: git log --oneline ${target_branch}..${branch_name} (what the epic branch changed)
1637
- 3. Run: git log --oneline ${branch_name}..${target_branch} (what target changed since branch point)
1638
- 4. Resolve each conflict by combining both sides' intent
1639
- 5. Stage each resolved file with: git add <filename>
1640
- 6. Do NOT commit ralph.sh will create the merge commit
1641
- 7. Do NOT run git merge --abort
1642
- 8. If you cannot safely resolve a conflict, leave the conflict markers in place
1711
+ 1. Stay in the current repository and operate on the existing in-progress merge state.
1712
+ 2. Do NOT delegate. Do NOT spawn merger, builder, planner, or validator work.
1713
+ 3. For each conflicted file listed above, read the full file and inspect the conflict markers.
1714
+ 4. Run: git log --oneline ${target_branch}..${branch_name} to see what the epic branch changed.
1715
+ 5. Run: git log --oneline ${branch_name}..${target_branch} to see what changed on the target branch.
1716
+ 6. Resolve each conflict by combining both sides' intent where possible.
1717
+ 7. Stage each resolved file with: git add <filename>.
1718
+ 8. Do NOT commit. ralph.sh will create the merge commit after all conflicts are resolved.
1719
+ 9. Do NOT run git merge --abort.
1720
+ 10. If you cannot safely resolve a conflict, leave the conflict markers in place.
1721
+
1722
+ When you are finished, print exactly one final line:
1723
+ - MERGE_SUCCESS
1724
+ - MERGE_FAILED
1643
1725
 
1644
1726
  Begin resolving."
1645
1727
 
@@ -1647,18 +1729,18 @@ Begin resolving."
1647
1729
 
1648
1730
  case "$BACKEND" in
1649
1731
  claude)
1650
- echo "$merge_prompt" | $AGENT_CMD --agent merger --model "$MODEL_MERGER" --dangerously-skip-permissions --print --verbose --output-format stream-json > "$merge_log" 2>&1 || true
1732
+ echo "$merge_prompt" | $AGENT_CMD --agent team-lead --model "$MODEL_TEAM_LEAD" --dangerously-skip-permissions --print --verbose --output-format stream-json > "$merge_log" 2>&1 || true
1651
1733
  ;;
1652
1734
  copilot)
1653
1735
  COPILOT_MERGE_PROMPT="$merge_prompt" \
1654
- script -q /dev/null /bin/sh -lc 'exec gh copilot -- --agent merger --allow-all --no-ask-user --stream on -p "$COPILOT_MERGE_PROMPT"' \
1736
+ script -q /dev/null /bin/sh -lc 'exec gh copilot -- --agent team-lead --allow-all --no-ask-user --stream on -p "$COPILOT_MERGE_PROMPT"' \
1655
1737
  > "$merge_log" 2>&1 || true
1656
1738
  ;;
1657
1739
  codex)
1658
- MODEL_TEAM_LEAD="$MODEL_MERGER" run_codex_exec "$ROOT_DIR" "$merge_prompt" > "$merge_log" 2>&1 || true
1740
+ run_codex_exec "$ROOT_DIR" "$merge_prompt" > "$merge_log" 2>&1 || true
1659
1741
  ;;
1660
1742
  opencode)
1661
- run_opencode_exec "$ROOT_DIR" "$merge_prompt" merger "$MODEL_MERGER" > "$merge_log" 2>&1 || true
1743
+ run_opencode_exec "$ROOT_DIR" "$merge_prompt" team-lead "$MODEL_TEAM_LEAD" > "$merge_log" 2>&1 || true
1662
1744
  ;;
1663
1745
  esac
1664
1746
 
@@ -1710,7 +1792,8 @@ collect_pending_merge_epics() {
1710
1792
  epic_id=$(rjq read "$PRD_FILE" ".epics[$epic_index].id")
1711
1793
  [ -n "$epic_id" ] || continue
1712
1794
 
1713
- local branch_name="ralph/${epic_id}"
1795
+ local branch_name
1796
+ branch_name=$(epic_branch_name "$epic_id")
1714
1797
  if git show-ref --verify --quiet "refs/heads/${branch_name}"; then
1715
1798
  pending_merge_ids+=("$epic_id")
1716
1799
  fi
@@ -1735,7 +1818,9 @@ recover_pending_merges() {
1735
1818
  echo " --- Recovering completed epic branches before ${context} ---"
1736
1819
  local epic_id
1737
1820
  for epic_id in "${pending_merge_ids[@]}"; do
1738
- echo " [$epic_id] Recovered pending merge from existing epic branch"
1821
+ local branch_name
1822
+ branch_name=$(epic_branch_name "$epic_id")
1823
+ echo " [$epic_id] Recovered pending merge from existing epic branch (${branch_name})"
1739
1824
  echo "[$epic_id] RECOVERED PENDING MERGE (${context}) — $(date)" >> "$PROGRESS_FILE"
1740
1825
  done
1741
1826
 
@@ -2147,18 +2232,30 @@ while true; do
2147
2232
  [ "$passed_s_prd" -gt "$passed_s" ] && passed_s="$passed_s_prd"
2148
2233
  local all_done=false
2149
2234
  [ "$passed_s" -eq "$total_s" ] && [ "$total_s" -gt 0 ] && all_done=true
2235
+ local live_merge_status=""
2236
+ live_merge_status=$(read_epic_merge_result_field "$finished_epic_id" .status "" 2>/dev/null || true)
2237
+ local merge_recorded=false
2238
+ if [ "$live_merge_status" = "merged" ] || [ "$live_merge_status" = "merge-failed" ]; then
2239
+ merge_recorded=true
2240
+ fi
2241
+ local epic_flow_complete=false
2242
+ if [ "$all_done" = true ] && [ "$merge_recorded" = true ]; then
2243
+ epic_flow_complete=true
2244
+ fi
2150
2245
 
2151
- if [ "$process_finished" = true ] || [ "$all_done" = true ]; then
2152
- # Treat fully-passed stories in the PRD as the authoritative completion
2153
- # signal, even if the backend session is still idling.
2154
- if [ "$process_finished" = false ]; then
2246
+ if [ "$process_finished" = true ] || [ "$epic_flow_complete" = true ]; then
2247
+ # Only terminate an in-flight session early after the Team Lead has
2248
+ # written the merge result artifact. Fully-passed stories alone are
2249
+ # not enough to declare the epic session complete.
2250
+ if [ "$process_finished" = false ] && [ "$epic_flow_complete" = true ]; then
2155
2251
  terminate_process_tree "${active_pids[$slot]}"
2156
2252
  fi
2157
2253
  wait "${active_pids[$slot]}" 2>/dev/null || true
2158
2254
 
2159
- # If the process exited before the epic reached all stories passed,
2160
- # consider it a crash and retry when possible.
2161
- if [ "$all_done" = false ]; then
2255
+ # If the process exited before the epic reached full completion
2256
+ # (stories passed plus merge result recorded), consider it a crash
2257
+ # and retry when possible.
2258
+ if [ "$epic_flow_complete" = false ]; then
2162
2259
  local retry_count
2163
2260
  retry_count="$(get_crash_retry_count "$finished_epic_id")"
2164
2261
  if [ "$retry_count" -lt "$MAX_CRASH_RETRIES" ]; then
@@ -2183,14 +2280,25 @@ while true; do
2183
2280
 
2184
2281
  echo " [$finished_epic_id] finished — processing result"
2185
2282
  project_state_to_prd "$finished_epic_id" || true
2283
+ local merge_status
2284
+ merge_status=$(read_epic_merge_result_field "$finished_epic_id" .status "" 2>/dev/null || true)
2285
+ if [ "$merge_status" = "merged" ] && ! verify_epic_branch_merged "$finished_epic_id"; then
2286
+ echo " [$finished_epic_id] Team Lead reported merge success but scripted check failed"
2287
+ echo "[$finished_epic_id] MERGE CHECK FAILED (team lead reported merged) — $(date)" >> "$PROGRESS_FILE"
2288
+ reset_epic_merge_result_file "$finished_epic_id"
2289
+ merge_status=""
2290
+ fi
2186
2291
  process_epic_result "${active_indices[$slot]}"
2187
- # Track completed epics for merge_wave
2292
+ # Track completed epics for merge_wave only when the Team Lead did not already merge.
2188
2293
  local post_status
2189
2294
  post_status=$(rjq read "$PRD_FILE" ".epics[${active_indices[$slot]}].status" "pending")
2190
- if [ "$post_status" = "completed" ]; then
2295
+ if [ "$post_status" = "completed" ] && [ "$merge_status" != "merged" ]; then
2191
2296
  wave_completed_ids+=("$finished_epic_id")
2192
2297
  fi
2193
2298
  cleanup_epic_worktree "$finished_epic_id"
2299
+ if [ "$merge_status" = "merged" ]; then
2300
+ delete_epic_branch "$finished_epic_id"
2301
+ fi
2194
2302
  unset 'active_pids[$slot]'
2195
2303
  unset 'active_indices[$slot]'
2196
2304
  unset 'active_start_times[$slot]'
@@ -2260,9 +2368,7 @@ while true; do
2260
2368
  fi
2261
2369
  done
2262
2370
 
2263
- if ! recover_pending_merges "finalization"; then
2264
- initialize_counters
2265
- fi
2371
+ recover_pending_merges "finalization" || true
2266
2372
  initialize_counters
2267
2373
 
2268
2374
  if ! run_final_validation_cycle; then