ralph-teams 1.0.31 → 1.0.34
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/builder.md +2 -1
- package/.claude/agents/final-validator.md +12 -3
- package/.codex/agents/builder.toml +2 -1
- package/.codex/agents/final-validator.toml +12 -3
- package/.github/agents/builder.agent.md +2 -1
- package/.github/agents/final-validator.agent.md +12 -3
- package/.opencode/agents/builder.md +2 -1
- package/.opencode/agents/final-validator.md +12 -3
- package/README.md +17 -13
- package/package.json +1 -1
- package/prompts/agents/builder.md +2 -1
- package/prompts/agents/final-validator.md +12 -3
- package/prompts/team-lead-policy.md +6 -1
- package/prompts/team-lead-runtime.md +9 -1
- package/ralph.sh +164 -136
|
@@ -21,7 +21,7 @@ You are the hands. You implement. You do NOT choose overall scope or verify your
|
|
|
21
21
|
3. **Understand the task** — Read the acceptance criteria or validation findings, the requested scope, and any retry feedback.
|
|
22
22
|
4. **Create or update automated tests first when they should change** — If planning context includes test work, implement those tests. If no planning context exists and the scope is new behavior, work TDD-style: define the automated tests first, confirm they fail on the current code, then proceed.
|
|
23
23
|
5. **Implement** — Write clean, minimal code that satisfies the assigned scope and makes the relevant tests pass.
|
|
24
|
-
6. **
|
|
24
|
+
6. **Use the Team Lead's setup commands when provided, then run quality checks** — If the Team Lead already provided bootstrap, build, or test commands, follow those exact commands first and do not rediscover them unless they fail. Otherwise determine the setup, build, and test commands from repo instructions and manifests. Check `AGENTS.md`, `README*`, and contributor docs first. Prefer repo-defined scripts or task runners over ecosystem defaults, then run the relevant verification commands for the assigned scope. Fix issues before committing.
|
|
25
25
|
7. **Commit** — Use a conventional commit message that matches the assigned scope.
|
|
26
26
|
8. **Get the commit SHA** — After committing, run `git rev-parse HEAD` to get the full commit SHA.
|
|
27
27
|
9. **Report back** — Return the exact commit SHA and a concise summary so validators can inspect exactly what changed.
|
|
@@ -58,6 +58,7 @@ If the Team Lead reassigns the scope with validator feedback:
|
|
|
58
58
|
- Keep changes minimal and focused on the acceptance criteria or findings.
|
|
59
59
|
- Do NOT gold-plate.
|
|
60
60
|
- Treat automated coverage as part of the assignment, not optional cleanup. Do not finish with zero new or updated tests unless the Team Lead explicitly said coverage is already sufficient or you can point to a concrete repository-based reason automated coverage is not possible.
|
|
61
|
+
- If the Team Lead gives exact bootstrap, build, or test commands, use them instead of re-probing the repository with generic commands. Only fall back to fresh command discovery if the provided commands fail or are clearly incomplete.
|
|
61
62
|
- Infer project commands from the repository before running them. Check `AGENTS.md`, `README*`, and repo instructions first, prefer repo-defined scripts and task runners, and only use generic ecosystem defaults when the repo is unambiguous.
|
|
62
63
|
- Do not validate your own work against the acceptance criteria beyond normal sanity checks. A separate validator may do that.
|
|
63
64
|
- Do NOT skip quality checks.
|
|
@@ -10,6 +10,8 @@ model: sonnet
|
|
|
10
10
|
|
|
11
11
|
You independently validate the final integrated branch after all epic work is complete. Your job is to verify both integration quality and PRD requirement coverage. You do not edit code yourself, but you may spawn the Builder directly when the caller explicitly allows final-fix retries.
|
|
12
12
|
|
|
13
|
+
Final validation also owns the last check for unresolved merge integration. If the PRD or run context shows `merge-failed` epics and the corresponding leftover epic branches still exist, you should inspect that state explicitly and attempt a clean merge retry before deciding PASS or FAIL.
|
|
14
|
+
|
|
13
15
|
## Workflow
|
|
14
16
|
|
|
15
17
|
1. Read the project and run context provided by the caller.
|
|
@@ -18,15 +20,19 @@ You independently validate the final integrated branch after all epic work is co
|
|
|
18
20
|
4. Run the relevant broad verification commands yourself.
|
|
19
21
|
5. Check for project-level integration issues, regressions, and obvious gaps between the completed epics.
|
|
20
22
|
6. Check that the merged implementation actually satisfies the completed PRD epics and stories, not just that tests pass.
|
|
21
|
-
7.
|
|
22
|
-
8.
|
|
23
|
-
9.
|
|
23
|
+
7. Check whether any epics are marked `merge-failed` in `prd.json`.
|
|
24
|
+
8. If a `merge-failed` epic still has a leftover epic branch, inspect it and attempt a clean merge retry yourself when it is safe to do so.
|
|
25
|
+
9. If a merge retry still conflicts or otherwise fails, treat that as a validation failure and report it explicitly.
|
|
26
|
+
10. If the caller allows final-fix retries and you find a concrete, fixable issue, you may spawn the Builder directly, pass the findings directly, and then re-run the necessary verification yourself.
|
|
27
|
+
11. Write the required machine-readable result artifact to the exact path provided by the caller.
|
|
28
|
+
12. Report a clear PASS or FAIL verdict with concrete fix items.
|
|
24
29
|
|
|
25
30
|
## Output Contract
|
|
26
31
|
|
|
27
32
|
- The caller will provide a `## Result Artifact Path` section containing an exact file path.
|
|
28
33
|
- The caller will provide a `## PRD File Path` section. Read that file yourself before deciding the verdict.
|
|
29
34
|
- The caller may provide an `Allowed final-fix retries` value. Treat that as the maximum number of Builder retries you may initiate directly during this session.
|
|
35
|
+
- The caller may also provide loop-branch and repository-root context. Use that information when checking leftover `merge-failed` epic branches.
|
|
30
36
|
- Before exiting, write a JSON file to that exact path.
|
|
31
37
|
- The JSON must include:
|
|
32
38
|
- `phase`: `"final-validation"`
|
|
@@ -49,6 +55,7 @@ You independently validate the final integrated branch after all epic work is co
|
|
|
49
55
|
### Findings
|
|
50
56
|
- PASS: [area that is verified]
|
|
51
57
|
- FAIL: [specific issue or missing PRD requirement]
|
|
58
|
+
- FAIL: [merge-failed epic still could not be integrated, with branch/conflict summary]
|
|
52
59
|
|
|
53
60
|
### Tests: PASS / FAIL
|
|
54
61
|
[summary]
|
|
@@ -64,6 +71,8 @@ You independently validate the final integrated branch after all epic work is co
|
|
|
64
71
|
|
|
65
72
|
- Never edit code yourself.
|
|
66
73
|
- If you spawn the Builder, keep ownership of the validation decision. The Builder only fixes; you still re-verify and decide PASS or FAIL.
|
|
74
|
+
- If `prd.json` contains `merge-failed` epics, you must treat that as part of final validation scope, not as an unrelated shell concern.
|
|
75
|
+
- You may attempt a clean merge retry for a leftover `merge-failed` epic branch, but do not hand merge-conflict resolution to a fresh Team Lead session from here.
|
|
67
76
|
- Do not exceed the allowed final-fix retry budget from the caller.
|
|
68
77
|
- Focus on whole-run integration, regression risks, and PRD requirement coverage.
|
|
69
78
|
- Fail the validation if the merged result misses or only partially implements required PRD behavior, even when existing tests pass.
|
|
@@ -18,7 +18,7 @@ You are the hands. You implement. You do NOT choose overall scope or verify your
|
|
|
18
18
|
3. **Understand the task** — Read the acceptance criteria or validation findings, the requested scope, and any retry feedback.
|
|
19
19
|
4. **Create or update automated tests first when they should change** — If planning context includes test work, implement those tests. If no planning context exists and the scope is new behavior, work TDD-style: define the automated tests first, confirm they fail on the current code, then proceed.
|
|
20
20
|
5. **Implement** — Write clean, minimal code that satisfies the assigned scope and makes the relevant tests pass.
|
|
21
|
-
6. **
|
|
21
|
+
6. **Use the Team Lead's setup commands when provided, then run quality checks** — If the Team Lead already provided bootstrap, build, or test commands, follow those exact commands first and do not rediscover them unless they fail. Otherwise determine the setup, build, and test commands from repo instructions and manifests. Check `AGENTS.md`, `README*`, and contributor docs first. Prefer repo-defined scripts or task runners over ecosystem defaults, then run the relevant verification commands for the assigned scope. Fix issues before committing.
|
|
22
22
|
7. **Commit** — Use a conventional commit message that matches the assigned scope.
|
|
23
23
|
8. **Get the commit SHA** — After committing, run `git rev-parse HEAD` to get the full commit SHA.
|
|
24
24
|
9. **Report back** — Return the exact commit SHA and a concise summary so validators can inspect exactly what changed.
|
|
@@ -55,6 +55,7 @@ If the Team Lead reassigns the scope with validator feedback:
|
|
|
55
55
|
- Keep changes minimal and focused on the acceptance criteria or findings.
|
|
56
56
|
- Do NOT gold-plate.
|
|
57
57
|
- Treat automated coverage as part of the assignment, not optional cleanup. Do not finish with zero new or updated tests unless the Team Lead explicitly said coverage is already sufficient or you can point to a concrete repository-based reason automated coverage is not possible.
|
|
58
|
+
- If the Team Lead gives exact bootstrap, build, or test commands, use them instead of re-probing the repository with generic commands. Only fall back to fresh command discovery if the provided commands fail or are clearly incomplete.
|
|
58
59
|
- Infer project commands from the repository before running them. Check `AGENTS.md`, `README*`, and repo instructions first, prefer repo-defined scripts and task runners, and only use generic ecosystem defaults when the repo is unambiguous.
|
|
59
60
|
- Do not validate your own work against the acceptance criteria beyond normal sanity checks. A separate validator may do that.
|
|
60
61
|
- Do NOT skip quality checks.
|
|
@@ -7,6 +7,8 @@ developer_instructions = """
|
|
|
7
7
|
|
|
8
8
|
You independently validate the final integrated branch after all epic work is complete. Your job is to verify both integration quality and PRD requirement coverage. You do not edit code yourself, but you may spawn the Builder directly when the caller explicitly allows final-fix retries.
|
|
9
9
|
|
|
10
|
+
Final validation also owns the last check for unresolved merge integration. If the PRD or run context shows `merge-failed` epics and the corresponding leftover epic branches still exist, you should inspect that state explicitly and attempt a clean merge retry before deciding PASS or FAIL.
|
|
11
|
+
|
|
10
12
|
## Workflow
|
|
11
13
|
|
|
12
14
|
1. Read the project and run context provided by the caller.
|
|
@@ -15,15 +17,19 @@ You independently validate the final integrated branch after all epic work is co
|
|
|
15
17
|
4. Run the relevant broad verification commands yourself.
|
|
16
18
|
5. Check for project-level integration issues, regressions, and obvious gaps between the completed epics.
|
|
17
19
|
6. Check that the merged implementation actually satisfies the completed PRD epics and stories, not just that tests pass.
|
|
18
|
-
7.
|
|
19
|
-
8.
|
|
20
|
-
9.
|
|
20
|
+
7. Check whether any epics are marked `merge-failed` in `prd.json`.
|
|
21
|
+
8. If a `merge-failed` epic still has a leftover epic branch, inspect it and attempt a clean merge retry yourself when it is safe to do so.
|
|
22
|
+
9. If a merge retry still conflicts or otherwise fails, treat that as a validation failure and report it explicitly.
|
|
23
|
+
10. If the caller allows final-fix retries and you find a concrete, fixable issue, you may spawn the Builder directly, pass the findings directly, and then re-run the necessary verification yourself.
|
|
24
|
+
11. Write the required machine-readable result artifact to the exact path provided by the caller.
|
|
25
|
+
12. Report a clear PASS or FAIL verdict with concrete fix items.
|
|
21
26
|
|
|
22
27
|
## Output Contract
|
|
23
28
|
|
|
24
29
|
- The caller will provide a `## Result Artifact Path` section containing an exact file path.
|
|
25
30
|
- The caller will provide a `## PRD File Path` section. Read that file yourself before deciding the verdict.
|
|
26
31
|
- The caller may provide an `Allowed final-fix retries` value. Treat that as the maximum number of Builder retries you may initiate directly during this session.
|
|
32
|
+
- The caller may also provide loop-branch and repository-root context. Use that information when checking leftover `merge-failed` epic branches.
|
|
27
33
|
- Before exiting, write a JSON file to that exact path.
|
|
28
34
|
- The JSON must include:
|
|
29
35
|
- `phase`: `"final-validation"`
|
|
@@ -46,6 +52,7 @@ You independently validate the final integrated branch after all epic work is co
|
|
|
46
52
|
### Findings
|
|
47
53
|
- PASS: [area that is verified]
|
|
48
54
|
- FAIL: [specific issue or missing PRD requirement]
|
|
55
|
+
- FAIL: [merge-failed epic still could not be integrated, with branch/conflict summary]
|
|
49
56
|
|
|
50
57
|
### Tests: PASS / FAIL
|
|
51
58
|
[summary]
|
|
@@ -61,6 +68,8 @@ You independently validate the final integrated branch after all epic work is co
|
|
|
61
68
|
|
|
62
69
|
- Never edit code yourself.
|
|
63
70
|
- If you spawn the Builder, keep ownership of the validation decision. The Builder only fixes; you still re-verify and decide PASS or FAIL.
|
|
71
|
+
- If `prd.json` contains `merge-failed` epics, you must treat that as part of final validation scope, not as an unrelated shell concern.
|
|
72
|
+
- You may attempt a clean merge retry for a leftover `merge-failed` epic branch, but do not hand merge-conflict resolution to a fresh Team Lead session from here.
|
|
64
73
|
- Do not exceed the allowed final-fix retry budget from the caller.
|
|
65
74
|
- Focus on whole-run integration, regression risks, and PRD requirement coverage.
|
|
66
75
|
- Fail the validation if the merged result misses or only partially implements required PRD behavior, even when existing tests pass.
|
|
@@ -21,7 +21,7 @@ You are the hands. You implement. You do NOT choose overall scope or verify your
|
|
|
21
21
|
3. **Understand the task** — Read the acceptance criteria or validation findings, the requested scope, and any retry feedback.
|
|
22
22
|
4. **Create or update automated tests first when they should change** — If planning context includes test work, implement those tests. If no planning context exists and the scope is new behavior, work TDD-style: define the automated tests first, confirm they fail on the current code, then proceed.
|
|
23
23
|
5. **Implement** — Write clean, minimal code that satisfies the assigned scope and makes the relevant tests pass.
|
|
24
|
-
6. **
|
|
24
|
+
6. **Use the Team Lead's setup commands when provided, then run quality checks** — If the Team Lead already provided bootstrap, build, or test commands, follow those exact commands first and do not rediscover them unless they fail. Otherwise determine the setup, build, and test commands from repo instructions and manifests. Check `AGENTS.md`, `README*`, and contributor docs first. Prefer repo-defined scripts or task runners over ecosystem defaults, then run the relevant verification commands for the assigned scope. Fix issues before committing.
|
|
25
25
|
7. **Commit** — Use a conventional commit message that matches the assigned scope.
|
|
26
26
|
8. **Get the commit SHA** — After committing, run `git rev-parse HEAD` to get the full commit SHA.
|
|
27
27
|
9. **Report back** — Return the exact commit SHA and a concise summary so validators can inspect exactly what changed.
|
|
@@ -58,6 +58,7 @@ If the Team Lead reassigns the scope with validator feedback:
|
|
|
58
58
|
- Keep changes minimal and focused on the acceptance criteria or findings.
|
|
59
59
|
- Do NOT gold-plate.
|
|
60
60
|
- Treat automated coverage as part of the assignment, not optional cleanup. Do not finish with zero new or updated tests unless the Team Lead explicitly said coverage is already sufficient or you can point to a concrete repository-based reason automated coverage is not possible.
|
|
61
|
+
- If the Team Lead gives exact bootstrap, build, or test commands, use them instead of re-probing the repository with generic commands. Only fall back to fresh command discovery if the provided commands fail or are clearly incomplete.
|
|
61
62
|
- Infer project commands from the repository before running them. Check `AGENTS.md`, `README*`, and repo instructions first, prefer repo-defined scripts and task runners, and only use generic ecosystem defaults when the repo is unambiguous.
|
|
62
63
|
- Do not validate your own work against the acceptance criteria beyond normal sanity checks. A separate validator may do that.
|
|
63
64
|
- Do NOT skip quality checks.
|
|
@@ -10,6 +10,8 @@ model: gpt-5.3-codex
|
|
|
10
10
|
|
|
11
11
|
You independently validate the final integrated branch after all epic work is complete. Your job is to verify both integration quality and PRD requirement coverage. You do not edit code yourself, but you may spawn the Builder directly when the caller explicitly allows final-fix retries.
|
|
12
12
|
|
|
13
|
+
Final validation also owns the last check for unresolved merge integration. If the PRD or run context shows `merge-failed` epics and the corresponding leftover epic branches still exist, you should inspect that state explicitly and attempt a clean merge retry before deciding PASS or FAIL.
|
|
14
|
+
|
|
13
15
|
## Workflow
|
|
14
16
|
|
|
15
17
|
1. Read the project and run context provided by the caller.
|
|
@@ -18,15 +20,19 @@ You independently validate the final integrated branch after all epic work is co
|
|
|
18
20
|
4. Run the relevant broad verification commands yourself.
|
|
19
21
|
5. Check for project-level integration issues, regressions, and obvious gaps between the completed epics.
|
|
20
22
|
6. Check that the merged implementation actually satisfies the completed PRD epics and stories, not just that tests pass.
|
|
21
|
-
7.
|
|
22
|
-
8.
|
|
23
|
-
9.
|
|
23
|
+
7. Check whether any epics are marked `merge-failed` in `prd.json`.
|
|
24
|
+
8. If a `merge-failed` epic still has a leftover epic branch, inspect it and attempt a clean merge retry yourself when it is safe to do so.
|
|
25
|
+
9. If a merge retry still conflicts or otherwise fails, treat that as a validation failure and report it explicitly.
|
|
26
|
+
10. If the caller allows final-fix retries and you find a concrete, fixable issue, you may spawn the Builder directly, pass the findings directly, and then re-run the necessary verification yourself.
|
|
27
|
+
11. Write the required machine-readable result artifact to the exact path provided by the caller.
|
|
28
|
+
12. Report a clear PASS or FAIL verdict with concrete fix items.
|
|
24
29
|
|
|
25
30
|
## Output Contract
|
|
26
31
|
|
|
27
32
|
- The caller will provide a `## Result Artifact Path` section containing an exact file path.
|
|
28
33
|
- The caller will provide a `## PRD File Path` section. Read that file yourself before deciding the verdict.
|
|
29
34
|
- The caller may provide an `Allowed final-fix retries` value. Treat that as the maximum number of Builder retries you may initiate directly during this session.
|
|
35
|
+
- The caller may also provide loop-branch and repository-root context. Use that information when checking leftover `merge-failed` epic branches.
|
|
30
36
|
- Before exiting, write a JSON file to that exact path.
|
|
31
37
|
- The JSON must include:
|
|
32
38
|
- `phase`: `"final-validation"`
|
|
@@ -49,6 +55,7 @@ You independently validate the final integrated branch after all epic work is co
|
|
|
49
55
|
### Findings
|
|
50
56
|
- PASS: [area that is verified]
|
|
51
57
|
- FAIL: [specific issue or missing PRD requirement]
|
|
58
|
+
- FAIL: [merge-failed epic still could not be integrated, with branch/conflict summary]
|
|
52
59
|
|
|
53
60
|
### Tests: PASS / FAIL
|
|
54
61
|
[summary]
|
|
@@ -64,6 +71,8 @@ You independently validate the final integrated branch after all epic work is co
|
|
|
64
71
|
|
|
65
72
|
- Never edit code yourself.
|
|
66
73
|
- If you spawn the Builder, keep ownership of the validation decision. The Builder only fixes; you still re-verify and decide PASS or FAIL.
|
|
74
|
+
- If `prd.json` contains `merge-failed` epics, you must treat that as part of final validation scope, not as an unrelated shell concern.
|
|
75
|
+
- You may attempt a clean merge retry for a leftover `merge-failed` epic branch, but do not hand merge-conflict resolution to a fresh Team Lead session from here.
|
|
67
76
|
- Do not exceed the allowed final-fix retry budget from the caller.
|
|
68
77
|
- Focus on whole-run integration, regression risks, and PRD requirement coverage.
|
|
69
78
|
- Fail the validation if the merged result misses or only partially implements required PRD behavior, even when existing tests pass.
|
|
@@ -21,7 +21,7 @@ You are the hands. You implement. You do NOT choose overall scope or verify your
|
|
|
21
21
|
3. **Understand the task** — Read the acceptance criteria or validation findings, the requested scope, and any retry feedback.
|
|
22
22
|
4. **Create or update automated tests first when they should change** — If planning context includes test work, implement those tests. If no planning context exists and the scope is new behavior, work TDD-style: define the automated tests first, confirm they fail on the current code, then proceed.
|
|
23
23
|
5. **Implement** — Write clean, minimal code that satisfies the assigned scope and makes the relevant tests pass.
|
|
24
|
-
6. **
|
|
24
|
+
6. **Use the Team Lead's setup commands when provided, then run quality checks** — If the Team Lead already provided bootstrap, build, or test commands, follow those exact commands first and do not rediscover them unless they fail. Otherwise determine the setup, build, and test commands from repo instructions and manifests. Check `AGENTS.md`, `README*`, and contributor docs first. Prefer repo-defined scripts or task runners over ecosystem defaults, then run the relevant verification commands for the assigned scope. Fix issues before committing.
|
|
25
25
|
7. **Commit** — Use a conventional commit message that matches the assigned scope.
|
|
26
26
|
8. **Get the commit SHA** — After committing, run `git rev-parse HEAD` to get the full commit SHA.
|
|
27
27
|
9. **Report back** — Return the exact commit SHA and a concise summary so validators can inspect exactly what changed.
|
|
@@ -58,6 +58,7 @@ If the Team Lead reassigns the scope with validator feedback:
|
|
|
58
58
|
- Keep changes minimal and focused on the acceptance criteria or findings.
|
|
59
59
|
- Do NOT gold-plate.
|
|
60
60
|
- Treat automated coverage as part of the assignment, not optional cleanup. Do not finish with zero new or updated tests unless the Team Lead explicitly said coverage is already sufficient or you can point to a concrete repository-based reason automated coverage is not possible.
|
|
61
|
+
- If the Team Lead gives exact bootstrap, build, or test commands, use them instead of re-probing the repository with generic commands. Only fall back to fresh command discovery if the provided commands fail or are clearly incomplete.
|
|
61
62
|
- Infer project commands from the repository before running them. Check `AGENTS.md`, `README*`, and repo instructions first, prefer repo-defined scripts and task runners, and only use generic ecosystem defaults when the repo is unambiguous.
|
|
62
63
|
- Do not validate your own work against the acceptance criteria beyond normal sanity checks. A separate validator may do that.
|
|
63
64
|
- Do NOT skip quality checks.
|
|
@@ -10,6 +10,8 @@ model: openai/gpt-5.3-codex
|
|
|
10
10
|
|
|
11
11
|
You independently validate the final integrated branch after all epic work is complete. Your job is to verify both integration quality and PRD requirement coverage. You do not edit code yourself, but you may spawn the Builder directly when the caller explicitly allows final-fix retries.
|
|
12
12
|
|
|
13
|
+
Final validation also owns the last check for unresolved merge integration. If the PRD or run context shows `merge-failed` epics and the corresponding leftover epic branches still exist, you should inspect that state explicitly and attempt a clean merge retry before deciding PASS or FAIL.
|
|
14
|
+
|
|
13
15
|
## Workflow
|
|
14
16
|
|
|
15
17
|
1. Read the project and run context provided by the caller.
|
|
@@ -18,15 +20,19 @@ You independently validate the final integrated branch after all epic work is co
|
|
|
18
20
|
4. Run the relevant broad verification commands yourself.
|
|
19
21
|
5. Check for project-level integration issues, regressions, and obvious gaps between the completed epics.
|
|
20
22
|
6. Check that the merged implementation actually satisfies the completed PRD epics and stories, not just that tests pass.
|
|
21
|
-
7.
|
|
22
|
-
8.
|
|
23
|
-
9.
|
|
23
|
+
7. Check whether any epics are marked `merge-failed` in `prd.json`.
|
|
24
|
+
8. If a `merge-failed` epic still has a leftover epic branch, inspect it and attempt a clean merge retry yourself when it is safe to do so.
|
|
25
|
+
9. If a merge retry still conflicts or otherwise fails, treat that as a validation failure and report it explicitly.
|
|
26
|
+
10. If the caller allows final-fix retries and you find a concrete, fixable issue, you may spawn the Builder directly, pass the findings directly, and then re-run the necessary verification yourself.
|
|
27
|
+
11. Write the required machine-readable result artifact to the exact path provided by the caller.
|
|
28
|
+
12. Report a clear PASS or FAIL verdict with concrete fix items.
|
|
24
29
|
|
|
25
30
|
## Output Contract
|
|
26
31
|
|
|
27
32
|
- The caller will provide a `## Result Artifact Path` section containing an exact file path.
|
|
28
33
|
- The caller will provide a `## PRD File Path` section. Read that file yourself before deciding the verdict.
|
|
29
34
|
- The caller may provide an `Allowed final-fix retries` value. Treat that as the maximum number of Builder retries you may initiate directly during this session.
|
|
35
|
+
- The caller may also provide loop-branch and repository-root context. Use that information when checking leftover `merge-failed` epic branches.
|
|
30
36
|
- Before exiting, write a JSON file to that exact path.
|
|
31
37
|
- The JSON must include:
|
|
32
38
|
- `phase`: `"final-validation"`
|
|
@@ -49,6 +55,7 @@ You independently validate the final integrated branch after all epic work is co
|
|
|
49
55
|
### Findings
|
|
50
56
|
- PASS: [area that is verified]
|
|
51
57
|
- FAIL: [specific issue or missing PRD requirement]
|
|
58
|
+
- FAIL: [merge-failed epic still could not be integrated, with branch/conflict summary]
|
|
52
59
|
|
|
53
60
|
### Tests: PASS / FAIL
|
|
54
61
|
[summary]
|
|
@@ -64,6 +71,8 @@ You independently validate the final integrated branch after all epic work is co
|
|
|
64
71
|
|
|
65
72
|
- Never edit code yourself.
|
|
66
73
|
- If you spawn the Builder, keep ownership of the validation decision. The Builder only fixes; you still re-verify and decide PASS or FAIL.
|
|
74
|
+
- If `prd.json` contains `merge-failed` epics, you must treat that as part of final validation scope, not as an unrelated shell concern.
|
|
75
|
+
- You may attempt a clean merge retry for a leftover `merge-failed` epic branch, but do not hand merge-conflict resolution to a fresh Team Lead session from here.
|
|
67
76
|
- Do not exceed the allowed final-fix retry budget from the caller.
|
|
68
77
|
- Focus on whole-run integration, regression risks, and PRD requirement coverage.
|
|
69
78
|
- Fail the validation if the merged result misses or only partially implements required PRD behavior, even when existing tests pass.
|
package/README.md
CHANGED
|
@@ -19,6 +19,7 @@ Many spec-driven tools are heavy, burn a lot of tokens, and are harder to adapt
|
|
|
19
19
|
|
|
20
20
|
The default `balanced` mode is intentionally simple:
|
|
21
21
|
- the Team Lead orchestrates the epic
|
|
22
|
+
- for clearly easy, low-risk mechanical work, the Team Lead may implement directly
|
|
22
23
|
- it can spawn the epic planner if needed
|
|
23
24
|
- it spawns one Builder per story attempt
|
|
24
25
|
- it validates inline or spawns a validator when independent verification is needed
|
|
@@ -43,18 +44,18 @@ This diagram shows the default `balanced` workflow only.
|
|
|
43
44
|
|
|
44
45
|
```mermaid
|
|
45
46
|
flowchart TD
|
|
46
|
-
A[Start run] --> B[Validate PRD and create loop branch]
|
|
47
|
+
A[Start run] --> B[Validate PRD and create loop branch plus loop worktree]
|
|
47
48
|
B --> C[Pick ready epic]
|
|
48
|
-
C --> D[Create worktree and epic branch]
|
|
49
|
+
C --> D[Create epic worktree and run-scoped epic branch]
|
|
49
50
|
D --> E[Team Lead decides on epic planner]
|
|
50
51
|
E --> F[Team Lead runs stories with builder]
|
|
51
52
|
F --> G{Epic validator needed?}
|
|
52
|
-
G -->|No| J[
|
|
53
|
+
G -->|No| J[Team Lead merges epic branch and writes merge artifact]
|
|
53
54
|
G -->|Yes| H[Run epic validator]
|
|
54
55
|
H -->|PASS| J
|
|
55
56
|
H -->|FAIL and retries left| I[Builder fixes epic-level findings]
|
|
56
57
|
I --> H
|
|
57
|
-
J --> K[If needed,
|
|
58
|
+
J --> K[If needed, fallback merge recovery handles leftovers]
|
|
58
59
|
K --> L{More epics?}
|
|
59
60
|
L -->|Yes| C
|
|
60
61
|
L -->|No| M{2+ epics and final validation enabled?}
|
|
@@ -74,7 +75,7 @@ Other presets:
|
|
|
74
75
|
|
|
75
76
|
At a high level:
|
|
76
77
|
- `ralph.sh` owns the run loop, worktrees, merges, resume state, and backend process lifecycle.
|
|
77
|
-
- one Team Lead session runs per epic and delegates to planner, builder, validator, and merger roles as needed.
|
|
78
|
+
- one Team Lead session runs per epic and delegates to planner, builder, validator, and merger roles as needed, or implements trivial work directly.
|
|
78
79
|
- `ralph.config.yml` controls backend choice, workflow toggles, parallelism, timeouts, and model selection.
|
|
79
80
|
|
|
80
81
|
Workflow presets:
|
|
@@ -534,6 +535,7 @@ During a run, Ralph writes:
|
|
|
534
535
|
- `.ralph-teams/progress.txt`: high-level run log
|
|
535
536
|
- `.ralph-teams/.worktrees/EPIC-xxx/`: isolated git worktree for an active epic
|
|
536
537
|
- `.ralph-teams/state/EPIC-xxx.json`: per-epic story pass/fail state (Team Lead reads/writes)
|
|
538
|
+
- `.ralph-teams/state/merge-EPIC-xxx.json`: per-epic merge-result artifact written by the Team Lead or merge recovery path
|
|
537
539
|
- `.ralph-teams/plans/plan-EPIC-xxx.md`: epic-planner output for an epic
|
|
538
540
|
- planned epics are expected to use these files as their implementation contract
|
|
539
541
|
- `.ralph-teams/logs/epic-EPIC-xxx-<timestamp>.log`: raw backend session log
|
|
@@ -551,12 +553,12 @@ The current execution contract is:
|
|
|
551
553
|
- blocked epics are skipped until dependencies are complete
|
|
552
554
|
- runs sequentially by default
|
|
553
555
|
- experimental wave parallelism is enabled only with `--parallel <n>`
|
|
554
|
-
- at run start Ralph auto-commits any dirty worktree changes, then creates a fresh loop branch
|
|
555
|
-
- each epic gets its own worktree and branch rooted from that loop branch
|
|
556
|
-
- before the Team Lead starts, Ralph creates the worktree and
|
|
556
|
+
- at run start Ralph auto-commits any dirty source-worktree changes, then creates a fresh loop branch and checks it out in `.ralph-teams/.worktrees/loop`
|
|
557
|
+
- each epic gets its own worktree and a run-scoped branch rooted from that loop branch, using `ralph/epic/<loop-run>/<epic-id>`
|
|
558
|
+
- before the Team Lead starts, Ralph creates the worktree and expects the Team Lead to establish that epic worktree's setup once, then hand the exact bootstrap, build, and test commands to Builders
|
|
557
559
|
- agents are expected to prefer repo-defined scripts and docs over generic ecosystem defaults when choosing setup and verification commands
|
|
558
560
|
- the shell-built Team Lead prompt must keep literal filenames shell-safe; do not add raw Markdown backticks inside that Bash string because Bash will treat them as command substitution
|
|
559
|
-
- when an epic completes,
|
|
561
|
+
- when an epic completes successfully, the Team Lead is expected to merge its epic branch back into the loop branch and write the merge-result artifact
|
|
560
562
|
- the backend team processes one epic per session
|
|
561
563
|
- stories run sequentially inside that epic
|
|
562
564
|
- already-passed stories are skipped
|
|
@@ -566,8 +568,10 @@ The current execution contract is:
|
|
|
566
568
|
- a Builder attempt only counts when the Team Lead receives a concrete commit SHA for that story attempt
|
|
567
569
|
- scoped validators check output independently from the builder's reasoning
|
|
568
570
|
- the Team Lead is expected to delegate early and not inspect the codebase beyond the minimum needed before delegation
|
|
569
|
-
-
|
|
570
|
-
-
|
|
571
|
+
- for clearly easy, low-risk mechanical tasks, the Team Lead may implement directly instead of delegating
|
|
572
|
+
- `DONE: X/Y stories passed` is a required session footer, but it is not enough to complete an epic on its own
|
|
573
|
+
- the durable epic-completion contract is: projected story state plus a valid merge-result artifact
|
|
574
|
+
- if PRD state says an epic is pending but the current loop branch already contains prior merge history for that run-scoped epic branch, Ralph fails fast instead of silently reusing stale history
|
|
571
575
|
- pressing `Ctrl-C` writes `.ralph-teams/ralph-state.json` so the run can be resumed later with `ralph-teams resume`
|
|
572
576
|
|
|
573
577
|
## Troubleshooting
|
|
@@ -634,9 +638,9 @@ Install or relink the package so the bundled JSON CLI is on your `PATH`:
|
|
|
634
638
|
npm install -g ralph-teams
|
|
635
639
|
```
|
|
636
640
|
|
|
637
|
-
### Ralph needs
|
|
641
|
+
### Ralph needs a clean base commit before creating the loop worktree
|
|
638
642
|
|
|
639
|
-
Ralph auto-commits current changes before creating
|
|
643
|
+
Ralph auto-commits current source-worktree changes before creating the loop branch and loop worktree. If you do not want that commit, clean up the worktree yourself before starting the run.
|
|
640
644
|
|
|
641
645
|
## Development
|
|
642
646
|
|
package/package.json
CHANGED
|
@@ -19,7 +19,7 @@ You are the hands. You implement. You do NOT choose overall scope or verify your
|
|
|
19
19
|
3. **Understand the task** — Read the acceptance criteria or validation findings, the requested scope, and any retry feedback.
|
|
20
20
|
4. **Create or update automated tests first when they should change** — If planning context includes test work, implement those tests. If no planning context exists and the scope is new behavior, work TDD-style: define the automated tests first, confirm they fail on the current code, then proceed.
|
|
21
21
|
5. **Implement** — Write clean, minimal code that satisfies the assigned scope and makes the relevant tests pass.
|
|
22
|
-
6. **
|
|
22
|
+
6. **Use the Team Lead's setup commands when provided, then run quality checks** — If the Team Lead already provided bootstrap, build, or test commands, follow those exact commands first and do not rediscover them unless they fail. Otherwise determine the setup, build, and test commands from repo instructions and manifests. Check `AGENTS.md`, `README*`, and contributor docs first. Prefer repo-defined scripts or task runners over ecosystem defaults, then run the relevant verification commands for the assigned scope. Fix issues before committing.
|
|
23
23
|
7. **Commit** — Use a conventional commit message that matches the assigned scope.
|
|
24
24
|
8. **Get the commit SHA** — After committing, run `git rev-parse HEAD` to get the full commit SHA.
|
|
25
25
|
9. **Report back** — Return the exact commit SHA and a concise summary so validators can inspect exactly what changed.
|
|
@@ -56,6 +56,7 @@ If the Team Lead reassigns the scope with validator feedback:
|
|
|
56
56
|
- Keep changes minimal and focused on the acceptance criteria or findings.
|
|
57
57
|
- Do NOT gold-plate.
|
|
58
58
|
- Treat automated coverage as part of the assignment, not optional cleanup. Do not finish with zero new or updated tests unless the Team Lead explicitly said coverage is already sufficient or you can point to a concrete repository-based reason automated coverage is not possible.
|
|
59
|
+
- If the Team Lead gives exact bootstrap, build, or test commands, use them instead of re-probing the repository with generic commands. Only fall back to fresh command discovery if the provided commands fail or are clearly incomplete.
|
|
59
60
|
- Infer project commands from the repository before running them. Check `AGENTS.md`, `README*`, and repo instructions first, prefer repo-defined scripts and task runners, and only use generic ecosystem defaults when the repo is unambiguous.
|
|
60
61
|
- Do not validate your own work against the acceptance criteria beyond normal sanity checks. A separate validator may do that.
|
|
61
62
|
- Do NOT skip quality checks.
|
|
@@ -8,6 +8,8 @@ title: "Final Validator Agent"
|
|
|
8
8
|
|
|
9
9
|
You independently validate the final integrated branch after all epic work is complete. Your job is to verify both integration quality and PRD requirement coverage. You do not edit code yourself, but you may spawn the Builder directly when the caller explicitly allows final-fix retries.
|
|
10
10
|
|
|
11
|
+
Final validation also owns the last check for unresolved merge integration. If the PRD or run context shows `merge-failed` epics and the corresponding leftover epic branches still exist, you should inspect that state explicitly and attempt a clean merge retry before deciding PASS or FAIL.
|
|
12
|
+
|
|
11
13
|
## Workflow
|
|
12
14
|
|
|
13
15
|
1. Read the project and run context provided by the caller.
|
|
@@ -16,15 +18,19 @@ You independently validate the final integrated branch after all epic work is co
|
|
|
16
18
|
4. Run the relevant broad verification commands yourself.
|
|
17
19
|
5. Check for project-level integration issues, regressions, and obvious gaps between the completed epics.
|
|
18
20
|
6. Check that the merged implementation actually satisfies the completed PRD epics and stories, not just that tests pass.
|
|
19
|
-
7.
|
|
20
|
-
8.
|
|
21
|
-
9.
|
|
21
|
+
7. Check whether any epics are marked `merge-failed` in `prd.json`.
|
|
22
|
+
8. If a `merge-failed` epic still has a leftover epic branch, inspect it and attempt a clean merge retry yourself when it is safe to do so.
|
|
23
|
+
9. If a merge retry still conflicts or otherwise fails, treat that as a validation failure and report it explicitly.
|
|
24
|
+
10. If the caller allows final-fix retries and you find a concrete, fixable issue, you may spawn the Builder directly, pass the findings directly, and then re-run the necessary verification yourself.
|
|
25
|
+
11. Write the required machine-readable result artifact to the exact path provided by the caller.
|
|
26
|
+
12. Report a clear PASS or FAIL verdict with concrete fix items.
|
|
22
27
|
|
|
23
28
|
## Output Contract
|
|
24
29
|
|
|
25
30
|
- The caller will provide a `## Result Artifact Path` section containing an exact file path.
|
|
26
31
|
- The caller will provide a `## PRD File Path` section. Read that file yourself before deciding the verdict.
|
|
27
32
|
- The caller may provide an `Allowed final-fix retries` value. Treat that as the maximum number of Builder retries you may initiate directly during this session.
|
|
33
|
+
- The caller may also provide loop-branch and repository-root context. Use that information when checking leftover `merge-failed` epic branches.
|
|
28
34
|
- Before exiting, write a JSON file to that exact path.
|
|
29
35
|
- The JSON must include:
|
|
30
36
|
- `phase`: `"final-validation"`
|
|
@@ -47,6 +53,7 @@ You independently validate the final integrated branch after all epic work is co
|
|
|
47
53
|
### Findings
|
|
48
54
|
- PASS: [area that is verified]
|
|
49
55
|
- FAIL: [specific issue or missing PRD requirement]
|
|
56
|
+
- FAIL: [merge-failed epic still could not be integrated, with branch/conflict summary]
|
|
50
57
|
|
|
51
58
|
### Tests: PASS / FAIL
|
|
52
59
|
[summary]
|
|
@@ -62,6 +69,8 @@ You independently validate the final integrated branch after all epic work is co
|
|
|
62
69
|
|
|
63
70
|
- Never edit code yourself.
|
|
64
71
|
- If you spawn the Builder, keep ownership of the validation decision. The Builder only fixes; you still re-verify and decide PASS or FAIL.
|
|
72
|
+
- If `prd.json` contains `merge-failed` epics, you must treat that as part of final validation scope, not as an unrelated shell concern.
|
|
73
|
+
- You may attempt a clean merge retry for a leftover `merge-failed` epic branch, but do not hand merge-conflict resolution to a fresh Team Lead session from here.
|
|
65
74
|
- Do not exceed the allowed final-fix retry budget from the caller.
|
|
66
75
|
- Focus on whole-run integration, regression risks, and PRD requirement coverage.
|
|
67
76
|
- Fail the validation if the merged result misses or only partially implements required PRD behavior, even when existing tests pass.
|
|
@@ -20,6 +20,10 @@ You coordinate epic execution. For clearly easy, low-risk mechanical tasks, you
|
|
|
20
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.
|
|
21
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`.
|
|
22
22
|
- Prefer explicit repository commands over generic ecosystem defaults even when the language is obvious.
|
|
23
|
+
- Before the first Builder for an epic, prepare the epic worktree environment once. Do not make each Builder rediscover basic setup from scratch.
|
|
24
|
+
- Start by checking whether the source checkout path provided in the runtime prompt already contains reusable dependency or generated setup artifacts that the epic worktree can safely reuse.
|
|
25
|
+
- If safe reuse is possible, materialize that reuse inside the epic worktree and continue. If reuse is not possible, run the repository's native bootstrap or install command inside the epic worktree before delegating implementation.
|
|
26
|
+
- Once the bootstrap, build, and test commands are established, pass the exact commands and any required environment-prep steps to every Builder for that epic.
|
|
23
27
|
- Only use generic defaults when the repository is unambiguous.
|
|
24
28
|
- If setup or verification remains ambiguous after inspection, do not guess wildly. Mark the attempt failed with a short concrete reason describing the ambiguity.
|
|
25
29
|
|
|
@@ -47,7 +51,8 @@ You coordinate epic execution. For clearly easy, low-risk mechanical tasks, you
|
|
|
47
51
|
|
|
48
52
|
- Before starting a story, check the epic state file. If the story has `passes: true`, skip it.
|
|
49
53
|
- 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.
|
|
50
|
-
- Before delegating
|
|
54
|
+
- Before delegating the first story, ensure the epic worktree environment is actually runnable.
|
|
55
|
+
- Before delegating any story, pass the exact bootstrap, build, and test commands already established for this epic to the Builder.
|
|
51
56
|
- If an epic plan exists, give the Builder the story, acceptance criteria, relevant plan section, and especially the story's planned test design.
|
|
52
57
|
- If a story planner was used, give the Builder the story planner output too.
|
|
53
58
|
- Require the Builder to add or update automated tests for the story and make them pass before the story can count as complete.
|
|
@@ -7,12 +7,20 @@ You are the Team Lead for this epic. Read the epic below and execute it.
|
|
|
7
7
|
ALL work for this epic MUST happen in this directory: {{WORKTREE_ABS_PATH}}
|
|
8
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
9
|
|
|
10
|
+
## Source Checkout
|
|
11
|
+
- Source checkout path: {{SOURCE_ROOT_DIR}}
|
|
12
|
+
- You may inspect this source checkout read-only to understand repo-level setup and to reuse existing dependency or build artifacts when that is safer or faster than reinstalling inside the epic worktree.
|
|
13
|
+
- Do NOT modify the source checkout during normal implementation. Any reuse should materialize inside the epic worktree, for example by creating a symlink there or copying a cacheable artifact into the worktree.
|
|
14
|
+
|
|
10
15
|
## Project Setup Strategy
|
|
11
16
|
- Ralph does not preinstall dependencies or preselect build/test commands for this repo.
|
|
12
|
-
- Before delegating implementation,
|
|
17
|
+
- Before delegating implementation, establish the epic worktree environment once for this epic: determine the setup, build, and test commands, then make the worktree runnable before the first Builder starts.
|
|
13
18
|
- 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
19
|
- 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
20
|
- Prefer explicit repository commands over generic ecosystem defaults.
|
|
21
|
+
- If the epic worktree is missing dependencies or other generated setup artifacts, first check whether the source checkout already has reusable artifacts that can be safely reused from the worktree.
|
|
22
|
+
- Prefer safe reuse from the source checkout when the repository structure and lockfiles make that reuse trustworthy; otherwise run the repository's native bootstrap/install step inside the epic worktree.
|
|
23
|
+
- After you determine the correct bootstrap, build, and test commands, pass those exact commands to every Builder for this epic and tell Builders not to rediscover them unless the provided commands fail.
|
|
16
24
|
- Only fall back to generic defaults when the repository is unambiguous.
|
|
17
25
|
- If setup remains ambiguous after inspection, stop guessing and fail the story attempt with a short concrete reason describing what you found.
|
|
18
26
|
|
package/ralph.sh
CHANGED
|
@@ -331,15 +331,17 @@ if [ ! -f "$PRD_FILE" ]; then
|
|
|
331
331
|
exit 1
|
|
332
332
|
fi
|
|
333
333
|
|
|
334
|
-
|
|
335
|
-
|
|
334
|
+
SOURCE_ROOT_DIR="$(pwd)"
|
|
335
|
+
ROOT_DIR="$SOURCE_ROOT_DIR"
|
|
336
|
+
LOOP_ROOT_DIR=""
|
|
337
|
+
RALPH_RUNTIME_DIR="${SOURCE_ROOT_DIR}/${RALPH_RUNTIME_DIRNAME}"
|
|
336
338
|
PROGRESS_FILE="${RALPH_RUNTIME_DIR}/progress.txt"
|
|
337
339
|
PLANS_DIR="${RALPH_RUNTIME_DIR}/plans"
|
|
338
340
|
LOGS_DIR="${RALPH_RUNTIME_DIR}/logs"
|
|
339
341
|
STATE_DIR="${RALPH_RUNTIME_DIR}/state"
|
|
340
342
|
WORKTREES_DIR="${RALPH_RUNTIME_DIR}/.worktrees"
|
|
341
343
|
|
|
342
|
-
|
|
344
|
+
repair_source_runtime_dir_if_needed() {
|
|
343
345
|
if [ -L "$RALPH_RUNTIME_DIR" ]; then
|
|
344
346
|
local runtime_link_target=""
|
|
345
347
|
runtime_link_target=$(readlink "$RALPH_RUNTIME_DIR" 2>/dev/null || true)
|
|
@@ -357,7 +359,7 @@ unstage_runtime_artifacts() {
|
|
|
357
359
|
git rm --cached -r --ignore-unmatch "$RALPH_RUNTIME_DIRNAME" >/dev/null 2>&1 || true
|
|
358
360
|
}
|
|
359
361
|
|
|
360
|
-
|
|
362
|
+
repair_source_runtime_dir_if_needed
|
|
361
363
|
mkdir -p "$RALPH_RUNTIME_DIR" "$PLANS_DIR" "$LOGS_DIR" "$STATE_DIR" "$WORKTREES_DIR"
|
|
362
364
|
|
|
363
365
|
ensure_runtime_rjq_bin() {
|
|
@@ -581,7 +583,7 @@ ensure_runtime_gitignore_entries() {
|
|
|
581
583
|
prompt_to_commit_dirty_worktree() {
|
|
582
584
|
local target_branch="$1"
|
|
583
585
|
|
|
584
|
-
echo "Worktree has uncommitted changes and Ralph needs
|
|
586
|
+
echo "Worktree has uncommitted changes and Ralph needs a clean base commit before creating loop worktree branch '$target_branch'."
|
|
585
587
|
echo "Ralph will now stage and commit all current changes before the run."
|
|
586
588
|
git status --short
|
|
587
589
|
git add -A
|
|
@@ -617,6 +619,15 @@ auto_remove_stale_worktree_dir() {
|
|
|
617
619
|
rm -rf "$worktree_path"
|
|
618
620
|
}
|
|
619
621
|
|
|
622
|
+
find_worktree_for_branch() {
|
|
623
|
+
local branch_name="$1"
|
|
624
|
+
|
|
625
|
+
git worktree list --porcelain 2>/dev/null | awk -v branch="refs/heads/${branch_name}" '
|
|
626
|
+
$1 == "worktree" { path = substr($0, 10); next }
|
|
627
|
+
$1 == "branch" && $2 == branch { print path; exit }
|
|
628
|
+
'
|
|
629
|
+
}
|
|
630
|
+
|
|
620
631
|
cleanup_epic_worktree_artifacts() {
|
|
621
632
|
local worktree_path="$1"
|
|
622
633
|
local branch_name="$2"
|
|
@@ -637,34 +648,56 @@ cleanup_epic_worktree_artifacts() {
|
|
|
637
648
|
git branch -D "$branch_name" >/dev/null 2>&1 || true
|
|
638
649
|
}
|
|
639
650
|
|
|
640
|
-
# --- Ensure loop branch exists and
|
|
651
|
+
# --- Ensure loop branch exists and has a dedicated worktree ---
|
|
641
652
|
ensure_runtime_gitignore_entries
|
|
642
653
|
ensure_repo_has_initial_commit
|
|
643
654
|
|
|
644
655
|
mkdir -p "$RALPH_RUNTIME_DIR" "$PLANS_DIR" "$LOGS_DIR" "$STATE_DIR" "$WORKTREES_DIR"
|
|
645
656
|
|
|
646
|
-
|
|
647
|
-
local
|
|
657
|
+
ensure_loop_worktree_ready() {
|
|
658
|
+
local loop_worktree_path="${WORKTREES_DIR}/loop"
|
|
659
|
+
local add_output=""
|
|
660
|
+
local retry_output=""
|
|
661
|
+
local existing_worktree=""
|
|
662
|
+
|
|
663
|
+
existing_worktree="$(find_worktree_for_branch "$LOOP_BRANCH" || true)"
|
|
664
|
+
if [ -n "$existing_worktree" ] && [ -d "$existing_worktree" ]; then
|
|
665
|
+
LOOP_ROOT_DIR="$existing_worktree"
|
|
666
|
+
ensure_worktree_runtime_link "$LOOP_ROOT_DIR"
|
|
667
|
+
return
|
|
668
|
+
fi
|
|
669
|
+
|
|
670
|
+
if ! git diff --quiet 2>/dev/null || ! git diff --cached --quiet 2>/dev/null; then
|
|
671
|
+
prompt_to_commit_dirty_worktree "$LOOP_BRANCH"
|
|
672
|
+
fi
|
|
648
673
|
|
|
649
|
-
if
|
|
650
|
-
|
|
651
|
-
|
|
674
|
+
if ! git show-ref --verify --quiet "refs/heads/${LOOP_BRANCH}"; then
|
|
675
|
+
echo "Creating loop branch: $LOOP_BRANCH (from $CURRENT_BRANCH)"
|
|
676
|
+
if ! add_output=$(git branch "$LOOP_BRANCH" "$CURRENT_BRANCH" 2>&1 >/dev/null); then
|
|
677
|
+
echo "Error: failed to create loop branch '$LOOP_BRANCH' from '$CURRENT_BRANCH'." >&2
|
|
678
|
+
[ -n "$add_output" ] && echo "$add_output" >&2
|
|
679
|
+
exit 1
|
|
652
680
|
fi
|
|
681
|
+
fi
|
|
653
682
|
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
683
|
+
git worktree prune >/dev/null 2>&1 || true
|
|
684
|
+
if [ -d "$loop_worktree_path" ] && ! git worktree list | grep -Fq "$loop_worktree_path"; then
|
|
685
|
+
auto_remove_stale_worktree_dir "$loop_worktree_path" "$LOOP_BRANCH"
|
|
686
|
+
fi
|
|
687
|
+
|
|
688
|
+
echo "Creating loop worktree: $loop_worktree_path ($LOOP_BRANCH)"
|
|
689
|
+
if ! add_output=$(git worktree add "$loop_worktree_path" "$LOOP_BRANCH" 2>&1 >/dev/null); then
|
|
690
|
+
echo "Loop worktree creation for '$LOOP_BRANCH' failed on the first attempt; pruning stale state and retrying once." >&2
|
|
691
|
+
[ -n "$add_output" ] && echo "$add_output" >&2
|
|
692
|
+
git worktree prune >/dev/null 2>&1 || true
|
|
693
|
+
git worktree remove "$loop_worktree_path" --force >/dev/null 2>&1 || true
|
|
694
|
+
if [ -d "$loop_worktree_path" ]; then
|
|
695
|
+
auto_remove_stale_worktree_dir "$loop_worktree_path" "$LOOP_BRANCH"
|
|
696
|
+
fi
|
|
697
|
+
if ! retry_output=$(git worktree add "$loop_worktree_path" "$LOOP_BRANCH" 2>&1 >/dev/null); then
|
|
698
|
+
echo "Error: failed to create loop worktree '$loop_worktree_path' for '$LOOP_BRANCH'." >&2
|
|
699
|
+
[ -n "$retry_output" ] && echo "$retry_output" >&2
|
|
700
|
+
exit 1
|
|
668
701
|
fi
|
|
669
702
|
fi
|
|
670
703
|
|
|
@@ -673,15 +706,17 @@ ensure_loop_branch_ready() {
|
|
|
673
706
|
exit 1
|
|
674
707
|
fi
|
|
675
708
|
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
709
|
+
LOOP_ROOT_DIR="$loop_worktree_path"
|
|
710
|
+
ensure_worktree_runtime_link "$LOOP_ROOT_DIR"
|
|
711
|
+
|
|
712
|
+
local loop_branch_name=""
|
|
713
|
+
loop_branch_name=$(git -C "$LOOP_ROOT_DIR" branch --show-current 2>/dev/null || echo "")
|
|
714
|
+
if [ "$loop_branch_name" != "$LOOP_BRANCH" ]; then
|
|
715
|
+
echo "Error: expected loop worktree branch '$LOOP_BRANCH' after setup, got '${loop_branch_name:-<none>}'." >&2
|
|
679
716
|
exit 1
|
|
680
717
|
fi
|
|
681
718
|
}
|
|
682
719
|
|
|
683
|
-
ensure_loop_branch_ready
|
|
684
|
-
|
|
685
720
|
epic_branch_name() {
|
|
686
721
|
local epic_id="$1"
|
|
687
722
|
echo "ralph/epic/${LOOP_BRANCH#ralph/}/${epic_id}"
|
|
@@ -746,7 +781,7 @@ create_epic_worktree() {
|
|
|
746
781
|
local epic_id="$1"
|
|
747
782
|
local branch_name
|
|
748
783
|
branch_name=$(epic_branch_name "$epic_id")
|
|
749
|
-
local worktree_path="${
|
|
784
|
+
local worktree_path="${WORKTREES_DIR}/${epic_id}"
|
|
750
785
|
local add_output
|
|
751
786
|
local retry_output
|
|
752
787
|
|
|
@@ -785,10 +820,20 @@ ensure_worktree_runtime_link() {
|
|
|
785
820
|
local worktree_abs_path="$1"
|
|
786
821
|
local worktree_runtime_path="${worktree_abs_path}/${RALPH_RUNTIME_DIRNAME}"
|
|
787
822
|
|
|
788
|
-
if [
|
|
823
|
+
if [ "$worktree_abs_path" = "$SOURCE_ROOT_DIR" ]; then
|
|
789
824
|
return 0
|
|
790
825
|
fi
|
|
791
826
|
|
|
827
|
+
if [ -L "$worktree_runtime_path" ]; then
|
|
828
|
+
local current_target
|
|
829
|
+
current_target="$(readlink "$worktree_runtime_path")"
|
|
830
|
+
if [ "$current_target" = "$RALPH_RUNTIME_DIR" ]; then
|
|
831
|
+
return 0
|
|
832
|
+
fi
|
|
833
|
+
log_warn "Stale runtime symlink in worktree (points to '${current_target}', expected '${RALPH_RUNTIME_DIR}') — relinking"
|
|
834
|
+
rm -f "$worktree_runtime_path"
|
|
835
|
+
fi
|
|
836
|
+
|
|
792
837
|
if [ -e "$worktree_runtime_path" ] && [ ! -L "$worktree_runtime_path" ]; then
|
|
793
838
|
rm -rf "$worktree_runtime_path"
|
|
794
839
|
fi
|
|
@@ -796,15 +841,20 @@ ensure_worktree_runtime_link() {
|
|
|
796
841
|
ln -s "$RALPH_RUNTIME_DIR" "$worktree_runtime_path"
|
|
797
842
|
}
|
|
798
843
|
|
|
844
|
+
ensure_loop_worktree_ready
|
|
845
|
+
ROOT_DIR="$LOOP_ROOT_DIR"
|
|
846
|
+
cd "$ROOT_DIR"
|
|
847
|
+
CURRENT_BRANCH=$(git branch --show-current 2>/dev/null || echo "")
|
|
848
|
+
|
|
799
849
|
# Removes a worktree. The branch is kept for potential merge by a later agent.
|
|
800
850
|
cleanup_epic_worktree() {
|
|
801
851
|
local epic_id="$1"
|
|
802
|
-
git worktree remove "${
|
|
852
|
+
git worktree remove "${WORKTREES_DIR}/${epic_id}" --force 2>/dev/null || true
|
|
803
853
|
}
|
|
804
854
|
|
|
805
855
|
# Removes ALL .worktrees/* entries (used on EXIT).
|
|
806
856
|
cleanup_all_worktrees() {
|
|
807
|
-
for dir in "${
|
|
857
|
+
for dir in "${WORKTREES_DIR}"/*/; do
|
|
808
858
|
[ -d "$dir" ] && git worktree remove "$dir" --force 2>/dev/null || true
|
|
809
859
|
done
|
|
810
860
|
}
|
|
@@ -912,8 +962,8 @@ CURRENT_STORY_ID=""
|
|
|
912
962
|
|
|
913
963
|
# Resolve absolute path to PRD file so team lead always has the correct path
|
|
914
964
|
PRD_ABS_PATH="$(cd "$(dirname "$PRD_FILE")" && pwd)/$(basename "$PRD_FILE")"
|
|
915
|
-
if [ "${PRD_ABS_PATH#"$
|
|
916
|
-
PRD_REL_PATH="${PRD_ABS_PATH#"$
|
|
965
|
+
if [ "${PRD_ABS_PATH#"$SOURCE_ROOT_DIR"/}" != "$PRD_ABS_PATH" ]; then
|
|
966
|
+
PRD_REL_PATH="${PRD_ABS_PATH#"$SOURCE_ROOT_DIR"/}"
|
|
917
967
|
else
|
|
918
968
|
PRD_REL_PATH="$(basename "$PRD_FILE")"
|
|
919
969
|
fi
|
|
@@ -1305,12 +1355,13 @@ prepare_codex_agent_configs
|
|
|
1305
1355
|
LOOP_STARTED_AT=$(date +%s)
|
|
1306
1356
|
|
|
1307
1357
|
# Cleanup worktrees on exit only when NOT interrupted (on interrupt, worktrees are preserved for resume)
|
|
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
|
|
1358
|
+
trap 'if [ "$INTERRUPTED" = false ]; then cd "$SOURCE_ROOT_DIR" 2>/dev/null || true; cleanup_all_worktrees; fi; [ -n "${CODEX_AGENT_RUNTIME_DIR:-}" ] && rm -rf "${CODEX_AGENT_RUNTIME_DIR}"; kill $(jobs -p) 2>/dev/null || true' EXIT
|
|
1309
1359
|
|
|
1310
1360
|
render_team_lead_prompt() {
|
|
1311
1361
|
TEAM_LEAD_TEMPLATE_PATH="$TEAM_LEAD_PROMPT_FILE" \
|
|
1312
1362
|
TEAM_LEAD_TEMPLATE_PROJECT="$PROJECT" \
|
|
1313
1363
|
TEAM_LEAD_TEMPLATE_WORKTREE_ABS_PATH="$WORKTREE_ABS_PATH" \
|
|
1364
|
+
TEAM_LEAD_TEMPLATE_SOURCE_ROOT_DIR="$SOURCE_ROOT_DIR" \
|
|
1314
1365
|
TEAM_LEAD_TEMPLATE_WORKTREE_STATE_FILE="$WORKTREE_STATE_FILE" \
|
|
1315
1366
|
TEAM_LEAD_TEMPLATE_WORKTREE_PRD_PATH="$WORKTREE_PRD_PATH" \
|
|
1316
1367
|
TEAM_LEAD_TEMPLATE_LOOP_BRANCH="$LOOP_BRANCH" \
|
|
@@ -1550,7 +1601,7 @@ spawn_epic_bg() {
|
|
|
1550
1601
|
local WORKTREE_PATH
|
|
1551
1602
|
WORKTREE_PATH=$(create_epic_worktree "$EPIC_ID")
|
|
1552
1603
|
local WORKTREE_ABS_PATH
|
|
1553
|
-
WORKTREE_ABS_PATH="$
|
|
1604
|
+
WORKTREE_ABS_PATH="$WORKTREE_PATH"
|
|
1554
1605
|
local EPIC_BRANCH
|
|
1555
1606
|
EPIC_BRANCH=$(epic_branch_name "$EPIC_ID")
|
|
1556
1607
|
ensure_worktree_runtime_link "$WORKTREE_ABS_PATH"
|
|
@@ -1586,7 +1637,11 @@ spawn_epic_bg() {
|
|
|
1586
1637
|
) &
|
|
1587
1638
|
elif [ "$BACKEND" = "codex" ]; then
|
|
1588
1639
|
(
|
|
1589
|
-
|
|
1640
|
+
if [ "$SOURCE_ROOT_DIR" != "$ROOT_DIR" ]; then
|
|
1641
|
+
run_codex_exec "$WORKTREE_ABS_PATH" "$TEAM_PROMPT" --add-dir "$ROOT_DIR" --add-dir "$SOURCE_ROOT_DIR" --add-dir "$SCRIPT_DIR" > "$EPIC_LOG" 2>&1
|
|
1642
|
+
else
|
|
1643
|
+
run_codex_exec "$WORKTREE_ABS_PATH" "$TEAM_PROMPT" --add-dir "$ROOT_DIR" --add-dir "$SCRIPT_DIR" > "$EPIC_LOG" 2>&1
|
|
1644
|
+
fi
|
|
1590
1645
|
) &
|
|
1591
1646
|
else
|
|
1592
1647
|
(
|
|
@@ -1599,10 +1654,10 @@ spawn_epic_bg() {
|
|
|
1599
1654
|
LAST_SPAWN_LOG="$EPIC_LOG"
|
|
1600
1655
|
}
|
|
1601
1656
|
|
|
1602
|
-
# merge_wave: fallback merge pass for
|
|
1603
|
-
#
|
|
1604
|
-
# Clean merges succeed without AI intervention. On conflict,
|
|
1605
|
-
#
|
|
1657
|
+
# merge_wave: fallback merge pass for epic branches that still exist after
|
|
1658
|
+
# their original Team Lead session. Takes epic IDs as arguments.
|
|
1659
|
+
# Clean merges succeed without AI intervention. On conflict, Ralph records the
|
|
1660
|
+
# merge failure and leaves the branch in place for a later clean retry.
|
|
1606
1661
|
merge_wave() {
|
|
1607
1662
|
local -a completed_epic_ids=("$@")
|
|
1608
1663
|
|
|
@@ -1623,6 +1678,8 @@ merge_wave() {
|
|
|
1623
1678
|
for epic_id in "${completed_epic_ids[@]}"; do
|
|
1624
1679
|
local branch_name
|
|
1625
1680
|
branch_name=$(epic_branch_name "$epic_id")
|
|
1681
|
+
local epic_index
|
|
1682
|
+
epic_index=$(rjq find-index "$PRD_FILE" .epics id "$epic_id")
|
|
1626
1683
|
|
|
1627
1684
|
# Check if branch exists
|
|
1628
1685
|
if ! git show-ref --verify --quiet "refs/heads/${branch_name}"; then
|
|
@@ -1647,15 +1704,18 @@ merge_wave() {
|
|
|
1647
1704
|
# be stripped before the merge result is recorded in git history.
|
|
1648
1705
|
if git merge "${branch_name}" --no-commit --no-ff 2>/dev/null; then
|
|
1649
1706
|
unstage_runtime_artifacts
|
|
1650
|
-
|
|
1707
|
+
repair_source_runtime_dir_if_needed
|
|
1651
1708
|
if [ -f ".git/MERGE_HEAD" ]; then
|
|
1652
1709
|
git commit --no-edit >/dev/null 2>&1 || true
|
|
1653
1710
|
fi
|
|
1711
|
+
if [ -n "$epic_index" ]; then
|
|
1712
|
+
rjq set "$PRD_FILE" ".epics[$epic_index].status" '"completed"'
|
|
1713
|
+
fi
|
|
1654
1714
|
echo " [$epic_id] Merge successful (clean)"
|
|
1655
1715
|
echo "[$epic_id] MERGED (clean) — $(date)" >> "$PROGRESS_FILE"
|
|
1656
1716
|
else
|
|
1657
1717
|
unstage_runtime_artifacts
|
|
1658
|
-
|
|
1718
|
+
repair_source_runtime_dir_if_needed
|
|
1659
1719
|
local conflicted_files
|
|
1660
1720
|
conflicted_files=$(git diff --name-only --diff-filter=U 2>/dev/null || true)
|
|
1661
1721
|
local conflict_count
|
|
@@ -1669,8 +1729,6 @@ merge_wave() {
|
|
|
1669
1729
|
[ -n "$merge_error" ] && echo " [$epic_id] Working tree state:" && printf '%s\n' "$merge_error" | sed 's/^/ /'
|
|
1670
1730
|
merge_failures=$((merge_failures + 1))
|
|
1671
1731
|
|
|
1672
|
-
local epic_index
|
|
1673
|
-
epic_index=$(rjq find-index "$PRD_FILE" .epics id "$epic_id")
|
|
1674
1732
|
if [ -n "$epic_index" ]; then
|
|
1675
1733
|
rjq set "$PRD_FILE" ".epics[$epic_index].status" '"merge-failed"'
|
|
1676
1734
|
fi
|
|
@@ -1687,90 +1745,25 @@ merge_wave() {
|
|
|
1687
1745
|
git checkout --ours -- prd.json
|
|
1688
1746
|
git add prd.json
|
|
1689
1747
|
git commit --no-edit >/dev/null 2>&1 || true
|
|
1748
|
+
if [ -n "$epic_index" ]; then
|
|
1749
|
+
rjq set "$PRD_FILE" ".epics[$epic_index].status" '"completed"'
|
|
1750
|
+
fi
|
|
1690
1751
|
echo " [$epic_id] Merge successful (kept projected prd.json)"
|
|
1691
1752
|
echo "[$epic_id] MERGED (projected prd.json) — $(date)" >> "$PROGRESS_FILE"
|
|
1692
1753
|
git branch -d "${branch_name}" 2>/dev/null || true
|
|
1693
1754
|
continue
|
|
1694
1755
|
fi
|
|
1695
1756
|
|
|
1696
|
-
|
|
1697
|
-
echo " [$epic_id]
|
|
1698
|
-
echo "[$epic_id]
|
|
1699
|
-
|
|
1700
|
-
local merge_prompt="You are the Team Lead. Take over this merge conflict resolution directly.
|
|
1701
|
-
|
|
1702
|
-
## Context
|
|
1703
|
-
- Target branch: ${target_branch}
|
|
1704
|
-
- Source branch: ${branch_name}
|
|
1705
|
-
- Epic ID: ${epic_id}
|
|
1706
|
-
|
|
1707
|
-
## Conflicted Files
|
|
1708
|
-
${conflicted_files}
|
|
1709
|
-
|
|
1710
|
-
## Instructions
|
|
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
|
|
1725
|
-
|
|
1726
|
-
Begin resolving."
|
|
1727
|
-
|
|
1728
|
-
local merge_log="${LOGS_DIR}/merge-${epic_id}-$(date +%s).log"
|
|
1729
|
-
|
|
1730
|
-
case "$BACKEND" in
|
|
1731
|
-
claude)
|
|
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
|
|
1733
|
-
;;
|
|
1734
|
-
copilot)
|
|
1735
|
-
COPILOT_MERGE_PROMPT="$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"' \
|
|
1737
|
-
> "$merge_log" 2>&1 || true
|
|
1738
|
-
;;
|
|
1739
|
-
codex)
|
|
1740
|
-
run_codex_exec "$ROOT_DIR" "$merge_prompt" > "$merge_log" 2>&1 || true
|
|
1741
|
-
;;
|
|
1742
|
-
opencode)
|
|
1743
|
-
run_opencode_exec "$ROOT_DIR" "$merge_prompt" team-lead "$MODEL_TEAM_LEAD" > "$merge_log" 2>&1 || true
|
|
1744
|
-
;;
|
|
1745
|
-
esac
|
|
1746
|
-
|
|
1747
|
-
# Check for remaining unresolved conflicts
|
|
1748
|
-
local remaining_conflicts
|
|
1749
|
-
remaining_conflicts=$(git diff --name-only --diff-filter=U 2>/dev/null || true)
|
|
1750
|
-
|
|
1751
|
-
# Also check if agent aborted the merge (MERGE_HEAD won't exist)
|
|
1752
|
-
if [ -z "$remaining_conflicts" ] && [ -f ".git/MERGE_HEAD" ]; then
|
|
1753
|
-
# All conflicts resolved — complete the merge commit
|
|
1754
|
-
git commit --no-edit 2>/dev/null || true
|
|
1755
|
-
echo " [$epic_id] merged (AI-resolved conflicts)"
|
|
1756
|
-
echo " [$epic_id] Merge log: ${merge_log}"
|
|
1757
|
-
echo "[$epic_id] MERGED (AI-resolved) — $(date)" >> "$PROGRESS_FILE"
|
|
1758
|
-
git branch -d "${branch_name}" 2>/dev/null || true
|
|
1759
|
-
else
|
|
1760
|
-
# AI failed or aborted — ensure clean state
|
|
1761
|
-
git merge --abort 2>/dev/null || true
|
|
1762
|
-
echo " [$epic_id] Merge FAILED — AI could not resolve conflicts in: ${conflicted_files}"
|
|
1763
|
-
echo " [$epic_id] Merge log: ${merge_log}"
|
|
1764
|
-
echo "[$epic_id] MERGE FAILED (AI resolution failed, files: ${conflicted_files}) — $(date)" >> "$PROGRESS_FILE"
|
|
1765
|
-
merge_failures=$((merge_failures + 1))
|
|
1757
|
+
git merge --abort 2>/dev/null || true
|
|
1758
|
+
echo " [$epic_id] Merge FAILED — conflicts remain; leaving ${branch_name} for a later clean retry"
|
|
1759
|
+
echo "[$epic_id] MERGE FAILED (conflicts remain, files: ${conflicted_files}) — $(date)" >> "$PROGRESS_FILE"
|
|
1760
|
+
merge_failures=$((merge_failures + 1))
|
|
1766
1761
|
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
epic_index=$(rjq find-index "$PRD_FILE" .epics id "$epic_id")
|
|
1770
|
-
if [ -n "$epic_index" ]; then
|
|
1771
|
-
rjq set "$PRD_FILE" ".epics[$epic_index].status" '"merge-failed"'
|
|
1772
|
-
fi
|
|
1762
|
+
if [ -n "$epic_index" ]; then
|
|
1763
|
+
rjq set "$PRD_FILE" ".epics[$epic_index].status" '"merge-failed"'
|
|
1773
1764
|
fi
|
|
1765
|
+
|
|
1766
|
+
continue
|
|
1774
1767
|
fi
|
|
1775
1768
|
|
|
1776
1769
|
# Clean up the merged branch
|
|
@@ -1786,7 +1779,7 @@ collect_pending_merge_epics() {
|
|
|
1786
1779
|
for epic_index in $(seq 0 $((TOTAL_EPICS - 1))); do
|
|
1787
1780
|
local epic_status
|
|
1788
1781
|
epic_status=$(rjq read "$PRD_FILE" ".epics[$epic_index].status" "pending")
|
|
1789
|
-
[ "$epic_status" = "completed" ] || continue
|
|
1782
|
+
[ "$epic_status" = "completed" ] || [ "$epic_status" = "merge-failed" ] || continue
|
|
1790
1783
|
|
|
1791
1784
|
local epic_id
|
|
1792
1785
|
epic_id=$(rjq read "$PRD_FILE" ".epics[$epic_index].id")
|
|
@@ -1863,17 +1856,32 @@ run_backend_agent_session() {
|
|
|
1863
1856
|
local prompt_file="${SCRIPT_DIR}/prompts/agents/${agent_name}.md"
|
|
1864
1857
|
local role_body
|
|
1865
1858
|
role_body="$(extract_prompt_body "$prompt_file")"
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1859
|
+
if [ "$SOURCE_ROOT_DIR" != "$ROOT_DIR" ]; then
|
|
1860
|
+
printf 'Runtime note: This Codex session runs in exec mode. `request_user_input` is unavailable. Never call it. Do not stop to ask the user questions. Make a reasonable assumption and continue.\n\n%s\n\n## Assignment\n%s\n' "$role_body" "$prompt" | codex \
|
|
1861
|
+
-a never \
|
|
1862
|
+
exec \
|
|
1863
|
+
-C "$workdir" \
|
|
1864
|
+
-m "$model" \
|
|
1865
|
+
-s workspace-write \
|
|
1866
|
+
--skip-git-repo-check \
|
|
1867
|
+
--color never \
|
|
1868
|
+
--add-dir "$ROOT_DIR" \
|
|
1869
|
+
--add-dir "$SOURCE_ROOT_DIR" \
|
|
1870
|
+
--add-dir "$SCRIPT_DIR" \
|
|
1871
|
+
- > "$log_file" 2>&1 || true
|
|
1872
|
+
else
|
|
1873
|
+
printf 'Runtime note: This Codex session runs in exec mode. `request_user_input` is unavailable. Never call it. Do not stop to ask the user questions. Make a reasonable assumption and continue.\n\n%s\n\n## Assignment\n%s\n' "$role_body" "$prompt" | codex \
|
|
1874
|
+
-a never \
|
|
1875
|
+
exec \
|
|
1876
|
+
-C "$workdir" \
|
|
1877
|
+
-m "$model" \
|
|
1878
|
+
-s workspace-write \
|
|
1879
|
+
--skip-git-repo-check \
|
|
1880
|
+
--color never \
|
|
1881
|
+
--add-dir "$ROOT_DIR" \
|
|
1882
|
+
--add-dir "$SCRIPT_DIR" \
|
|
1883
|
+
- > "$log_file" 2>&1 || true
|
|
1884
|
+
fi
|
|
1877
1885
|
;;
|
|
1878
1886
|
esac
|
|
1879
1887
|
}
|
|
@@ -1903,7 +1911,7 @@ read_final_validation_verdict() {
|
|
|
1903
1911
|
|
|
1904
1912
|
run_final_validation_cycle() {
|
|
1905
1913
|
[ "$FINAL_VALIDATION_ENABLED" = "1" ] || return 0
|
|
1906
|
-
[
|
|
1914
|
+
[ $((COMPLETED + FAILED)) -eq "$TOTAL_EPICS" ] || return 0
|
|
1907
1915
|
[ "$TOTAL_EPICS" -ge 2 ] || return 0
|
|
1908
1916
|
|
|
1909
1917
|
echo ""
|
|
@@ -1971,6 +1979,24 @@ $validation_result_file
|
|
|
1971
1979
|
|
|
1972
1980
|
}
|
|
1973
1981
|
|
|
1982
|
+
persist_loop_branch_state_if_dirty() {
|
|
1983
|
+
local dirty_status=""
|
|
1984
|
+
dirty_status=$(git status --porcelain --untracked-files=no 2>/dev/null || true)
|
|
1985
|
+
[ -n "$dirty_status" ] || return 0
|
|
1986
|
+
|
|
1987
|
+
git add -u
|
|
1988
|
+
unstage_runtime_artifacts
|
|
1989
|
+
|
|
1990
|
+
if git diff --cached --quiet >/dev/null 2>&1; then
|
|
1991
|
+
git reset >/dev/null 2>&1 || true
|
|
1992
|
+
return 0
|
|
1993
|
+
fi
|
|
1994
|
+
|
|
1995
|
+
if git commit -m "chore: persist loop branch state" >/dev/null 2>&1; then
|
|
1996
|
+
echo "Persisted loop branch state on ${LOOP_BRANCH}"
|
|
1997
|
+
fi
|
|
1998
|
+
}
|
|
1999
|
+
|
|
1974
2000
|
if ! recover_pending_merges "resume/startup"; then
|
|
1975
2001
|
initialize_counters
|
|
1976
2002
|
fi
|
|
@@ -2375,6 +2401,8 @@ if ! run_final_validation_cycle; then
|
|
|
2375
2401
|
FAILED=$((FAILED + 1))
|
|
2376
2402
|
fi
|
|
2377
2403
|
|
|
2404
|
+
persist_loop_branch_state_if_dirty
|
|
2405
|
+
|
|
2378
2406
|
# --- Summary ---
|
|
2379
2407
|
REMAINING=$((TOTAL_EPICS - COMPLETED - FAILED))
|
|
2380
2408
|
echo ""
|