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.
- package/.claude/agents/epic-planner.md +1 -1
- package/.claude/agents/team-lead.md +15 -8
- package/.codex/agents/epic-planner.toml +1 -1
- package/.github/agents/epic-planner.agent.md +1 -1
- package/.opencode/agents/epic-planner.md +1 -1
- package/README.md +6 -3
- package/dist/commands/task.d.ts +5 -0
- package/dist/commands/task.d.ts.map +1 -1
- package/dist/commands/task.js +49 -25
- package/dist/commands/task.js.map +1 -1
- package/package.json +1 -1
- package/prompts/agents/epic-planner.md +1 -1
- package/prompts/team-lead-policy.md +25 -13
- package/prompts/team-lead-runtime.md +93 -0
- package/ralph.sh +239 -133
|
@@ -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
|
|
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
|
|
14
|
-
-
|
|
15
|
-
- When
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
package/dist/commands/task.d.ts
CHANGED
|
@@ -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,
|
|
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"}
|
package/dist/commands/task.js
CHANGED
|
@@ -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
|
|
246
|
-
|
|
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
|
@@ -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
|
|
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.
|
|
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
|
|
33
|
-
- Treat an epic planner response as incomplete if it only pastes or summarizes the plan in chat
|
|
34
|
-
- Before using a newly generated plan, verify that the plan file exists at the required path. If
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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:
|
|
1529
|
-
#
|
|
1530
|
-
#
|
|
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
|
|
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 —
|
|
1621
|
-
echo " [$epic_id] conflicts detected —
|
|
1622
|
-
echo "[$epic_id] merge conflicts —
|
|
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
|
|
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.
|
|
1636
|
-
2.
|
|
1637
|
-
3.
|
|
1638
|
-
4.
|
|
1639
|
-
5.
|
|
1640
|
-
6.
|
|
1641
|
-
7.
|
|
1642
|
-
8.
|
|
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
|
|
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
|
|
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
|
-
|
|
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"
|
|
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
|
|
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
|
-
|
|
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 ] || [ "$
|
|
2152
|
-
#
|
|
2153
|
-
#
|
|
2154
|
-
|
|
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
|
|
2160
|
-
# consider it a crash
|
|
2161
|
-
|
|
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
|
-
|
|
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
|