@urateam/core 0.1.10 → 0.1.11
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/dist/__tests__/extract-handoff.test.js +125 -0
- package/dist/__tests__/extract-handoff.test.js.map +1 -1
- package/dist/__tests__/pr-description.test.js +51 -0
- package/dist/__tests__/pr-description.test.js.map +1 -1
- package/dist/__tests__/ralph.test.js +45 -3
- package/dist/__tests__/ralph.test.js.map +1 -1
- package/dist/executor/extract-handoff.d.ts.map +1 -1
- package/dist/executor/extract-handoff.js +33 -4
- package/dist/executor/extract-handoff.js.map +1 -1
- package/dist/executor/handoff.d.ts.map +1 -1
- package/dist/executor/handoff.js +32 -8
- package/dist/executor/handoff.js.map +1 -1
- package/dist/executor/ralph.d.ts +15 -0
- package/dist/executor/ralph.d.ts.map +1 -1
- package/dist/executor/ralph.js +24 -3
- package/dist/executor/ralph.js.map +1 -1
- package/dist/pipeline/pr-description.d.ts +12 -0
- package/dist/pipeline/pr-description.d.ts.map +1 -1
- package/dist/pipeline/pr-description.js +14 -3
- package/dist/pipeline/pr-description.js.map +1 -1
- package/dist/pipeline/runner.d.ts.map +1 -1
- package/dist/pipeline/runner.js +58 -8
- package/dist/pipeline/runner.js.map +1 -1
- package/package.json +1 -1
package/dist/executor/handoff.js
CHANGED
|
@@ -3,12 +3,18 @@ import { parseJsonBlock } from "./agent-stream.js";
|
|
|
3
3
|
import { createLogger } from "../logger.js";
|
|
4
4
|
const log = createLogger({ component: "Handoff" });
|
|
5
5
|
export function buildFallback(metadata, summary) {
|
|
6
|
-
// Note (urateam#
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
6
|
+
// Note (urateam#97): callers should NOT use this raw `summary` string
|
|
7
|
+
// for end-user surfaces. The slow path in extract-handoff.ts applies
|
|
8
|
+
// a JSON-soup heuristic before assigning to artifact.summary so the
|
|
9
|
+
// PR body's "## Summary" section doesn't render review-finding JSON
|
|
10
|
+
// fragments verbatim (rotulus#7 reproduction). buildFallback itself is
|
|
11
|
+
// schema-required to populate `summary` to satisfy HandoffArtifact;
|
|
12
|
+
// the sanitization logically belongs at the call site, not here.
|
|
13
|
+
//
|
|
14
|
+
// The deeper root cause — per-stage prompts in templates.ts never
|
|
15
|
+
// instruct the agent to emit a HandoffArtifact JSON block — is tracked
|
|
16
|
+
// in urateam#97 as the long-term fix. When that lands, the fast path
|
|
17
|
+
// becomes load-bearing and this fallback is rarely hit.
|
|
12
18
|
return {
|
|
13
19
|
...metadata,
|
|
14
20
|
summary: summary || `Stage ${metadata.stage} completed without structured output`,
|
|
@@ -44,7 +50,20 @@ export function parseHandoffArtifact(agentOutput, runId, issueId, stage) {
|
|
|
44
50
|
};
|
|
45
51
|
const parsed = parseJsonBlock(agentOutput);
|
|
46
52
|
if (!parsed) {
|
|
47
|
-
|
|
53
|
+
// Demoted from error → debug: this fires on EVERY implement/test stage
|
|
54
|
+
// because per-stage prompts in `packages/core/src/executor/prompt/templates.ts`
|
|
55
|
+
// never instruct the agent to emit a HandoffArtifact-shaped JSON block.
|
|
56
|
+
// The slow path in extractHandoff reconstructs filesChanged from git diff
|
|
57
|
+
// and provides a sanitized summary, so this isn't an actionable error —
|
|
58
|
+
// it's expected operation. Logging at error level falsely flagged it as
|
|
59
|
+
// a problem in every operator dashboard (and triggered Slack alerts via
|
|
60
|
+
// notifier/slack-alerts.ts which fires on level >= 50). See urateam#97.
|
|
61
|
+
//
|
|
62
|
+
// CONTRACT FOR FLIP-BACK: when (a) the per-stage prompts in templates.ts
|
|
63
|
+
// are updated to request a HandoffArtifact JSON block, AND (b) the fast
|
|
64
|
+
// path actually reaches `structured: true` on a meaningful fraction of
|
|
65
|
+
// runs, this log should flip back to warn. Track via urateam#97.
|
|
66
|
+
log.debug({ stage }, "no valid JSON block in agent output, using slow-path reconstruction");
|
|
48
67
|
return {
|
|
49
68
|
artifact: buildFallback(metadata, agentOutput.slice(0, 500)),
|
|
50
69
|
structured: false,
|
|
@@ -58,7 +77,12 @@ export function parseHandoffArtifact(agentOutput, runId, issueId, stage) {
|
|
|
58
77
|
};
|
|
59
78
|
const result = HandoffArtifactSchema.safeParse(fullArtifact);
|
|
60
79
|
if (!result.success) {
|
|
61
|
-
|
|
80
|
+
// Same demotion as the no-block case above (urateam#97); same
|
|
81
|
+
// flip-back contract. The review stage routinely emits review-findings
|
|
82
|
+
// JSON (severity/file/line shape, see security/review-checklist.ts
|
|
83
|
+
// REVIEW_OUTPUT_FORMAT) which fails this validation. That's expected
|
|
84
|
+
// operation, not an error.
|
|
85
|
+
log.debug({ stage, validationErrors: result.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join(", ") }, "JSON block did not match HandoffArtifact schema, using slow-path reconstruction");
|
|
62
86
|
return {
|
|
63
87
|
artifact: buildFallback(metadata, agentOutput.slice(0, 500)),
|
|
64
88
|
structured: false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handoff.js","sourceRoot":"","sources":["../../src/executor/handoff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEpD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,GAAG,GAAG,YAAY,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;AAQnD,MAAM,UAAU,aAAa,CAC3B,QAA8E,EAC9E,OAAe;IAEf,
|
|
1
|
+
{"version":3,"file":"handoff.js","sourceRoot":"","sources":["../../src/executor/handoff.ts"],"names":[],"mappings":"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"}
|
package/dist/executor/ralph.d.ts
CHANGED
|
@@ -4,6 +4,21 @@ export interface RalphCheckResult {
|
|
|
4
4
|
satisfied: boolean;
|
|
5
5
|
gaps: string[];
|
|
6
6
|
suggestions: string[];
|
|
7
|
+
/**
|
|
8
|
+
* Set when the requirements-check agent itself failed (threw, ran out of
|
|
9
|
+
* turns, or produced no parseable JSON). Distinct from `satisfied: false`
|
|
10
|
+
* with a populated `gaps` list — that means the agent ran successfully and
|
|
11
|
+
* found real gaps. `evaluationFailed: true` means we have NO information
|
|
12
|
+
* about whether the criteria were met.
|
|
13
|
+
*
|
|
14
|
+
* Callers should treat this as "must surface to a human" — it is NEVER
|
|
15
|
+
* safe to treat as `satisfied: true`, but also wasteful to feed back
|
|
16
|
+
* into a re-implement loop because retrying the same eval-failure
|
|
17
|
+
* conditions will probably hit the same wall.
|
|
18
|
+
*/
|
|
19
|
+
evaluationFailed?: boolean;
|
|
20
|
+
/** Human-readable reason for the evaluation failure. Used in PR-body draft notes. */
|
|
21
|
+
evaluationError?: string;
|
|
7
22
|
}
|
|
8
23
|
/**
|
|
9
24
|
* Check whether the implementation satisfies the issue's acceptance criteria.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ralph.d.ts","sourceRoot":"","sources":["../../src/executor/ralph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AASvD,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,WAAW,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"ralph.d.ts","sourceRoot":"","sources":["../../src/executor/ralph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AASvD,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB;;;;;;;;;;;OAWG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,qFAAqF;IACrF,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,kBAAkB,EAC3B,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,gBAAgB,CAAC,CA6G3B;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,gBAAgB,EAC7B,eAAe,EAAE,eAAe,GAC/B,MAAM,CAoBR"}
|
package/dist/executor/ralph.js
CHANGED
|
@@ -76,14 +76,35 @@ Be strict but fair. If the code addresses the intent of a criterion even if not
|
|
|
76
76
|
suggestions: Array.isArray(parsed.suggestions) ? parsed.suggestions : [],
|
|
77
77
|
};
|
|
78
78
|
}
|
|
79
|
+
// Agent ran but emitted no parseable JSON — we have NO evidence the
|
|
80
|
+
// criteria were checked. Fail closed. Surfacing this as `satisfied:
|
|
81
|
+
// false + evaluationFailed: true` lets the caller draft the PR with an
|
|
82
|
+
// honest "RALPH eval failed, human review required" note rather than
|
|
83
|
+
// silently shipping it as ready (urateam follow-up to PR #95 fail-open
|
|
84
|
+
// observed during rotulus#17 OSS validation).
|
|
79
85
|
log.warn("requirements check agent did not produce structured output");
|
|
80
|
-
return {
|
|
86
|
+
return {
|
|
87
|
+
satisfied: false,
|
|
88
|
+
gaps: [],
|
|
89
|
+
suggestions: [],
|
|
90
|
+
evaluationFailed: true,
|
|
91
|
+
evaluationError: "RALPH check agent completed but produced no parseable structured output — gaps could not be evaluated",
|
|
92
|
+
};
|
|
81
93
|
}
|
|
82
94
|
catch (error) {
|
|
83
95
|
const msg = error instanceof Error ? error.message : String(error);
|
|
84
96
|
log.error({ err: msg }, "requirements check agent failed");
|
|
85
|
-
//
|
|
86
|
-
|
|
97
|
+
// Same fail-closed semantics as the no-JSON case above. The previous
|
|
98
|
+
// behavior here returned satisfied: true with a comment "Don't block
|
|
99
|
+
// the pipeline on check failure" — that masked real failures (e.g., the
|
|
100
|
+
// 6-turn cap exhaustion observed on rotulus#17) as positive signals.
|
|
101
|
+
return {
|
|
102
|
+
satisfied: false,
|
|
103
|
+
gaps: [],
|
|
104
|
+
suggestions: [],
|
|
105
|
+
evaluationFailed: true,
|
|
106
|
+
evaluationError: `RALPH check agent failed: ${msg}`,
|
|
107
|
+
};
|
|
87
108
|
}
|
|
88
109
|
}
|
|
89
110
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ralph.js","sourceRoot":"","sources":["../../src/executor/ralph.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjD,MAAM,GAAG,GAAG,YAAY,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;AACjD,MAAM,WAAW,GAAG,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"ralph.js","sourceRoot":"","sources":["../../src/executor/ralph.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,6 +13,18 @@ export interface PRDescriptionOptions {
|
|
|
13
13
|
ralphSatisfied?: boolean;
|
|
14
14
|
/** List of unmet RALPH gap items (used for count in draft reason). */
|
|
15
15
|
ralphGaps?: unknown[];
|
|
16
|
+
/**
|
|
17
|
+
* Set when the RALPH check agent itself failed (threw, hit its turn cap,
|
|
18
|
+
* or produced no parseable JSON). Distinct from `ralphSatisfied: false`
|
|
19
|
+
* with a non-empty gap list — that means RALPH ran successfully and found
|
|
20
|
+
* real gaps. When this is true, the draft reason wording switches from
|
|
21
|
+
* "RALPH found N unmet acceptance criteria" to "RALPH evaluation failed:
|
|
22
|
+
* <reason>" so reviewers don't waste time hunting for a non-existent
|
|
23
|
+
* failed requirement (urateam#108).
|
|
24
|
+
*/
|
|
25
|
+
ralphEvaluationFailed?: boolean;
|
|
26
|
+
/** Human-readable reason from `RalphCheckResult.evaluationError`. */
|
|
27
|
+
ralphEvaluationError?: string;
|
|
16
28
|
/** Blocking review findings that remain unresolved (used for count in draft reason). */
|
|
17
29
|
unresolvedBlockingFindings?: unknown[];
|
|
18
30
|
/** Agent-authored commit messages (not auto-committed fallbacks) to include in a Commits section. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pr-description.d.ts","sourceRoot":"","sources":["../../src/pipeline/pr-description.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,kGAAkG;IAClG,OAAO,EAAE,eAAe,GAAG,SAAS,CAAC;IACrC,4EAA4E;IAC5E,OAAO,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,0FAA0F;IAC1F,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,sEAAsE;IACtE,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC;IACtB,wFAAwF;IACxF,0BAA0B,CAAC,EAAE,OAAO,EAAE,CAAC;IACvC,qGAAqG;IACrG,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"pr-description.d.ts","sourceRoot":"","sources":["../../src/pipeline/pr-description.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,kGAAkG;IAClG,OAAO,EAAE,eAAe,GAAG,SAAS,CAAC;IACrC,4EAA4E;IAC5E,OAAO,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,0FAA0F;IAC1F,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,sEAAsE;IACtE,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC;IACtB;;;;;;;;OAQG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,qEAAqE;IACrE,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,wFAAwF;IACxF,0BAA0B,CAAC,EAAE,OAAO,EAAE,CAAC;IACvC,qGAAqG;IACrG,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAoE3E"}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* Sections are separated by double newlines (markdown paragraph breaks).
|
|
13
13
|
*/
|
|
14
14
|
export function generatePRDescription(options) {
|
|
15
|
-
const { handoff, issueId, shouldDraft = false, ralphSatisfied = true, ralphGaps = [], unresolvedBlockingFindings = [], agentCommits = [], } = options;
|
|
15
|
+
const { handoff, issueId, shouldDraft = false, ralphSatisfied = true, ralphGaps = [], ralphEvaluationFailed = false, ralphEvaluationError, unresolvedBlockingFindings = [], agentCommits = [], } = options;
|
|
16
16
|
const parts = [];
|
|
17
17
|
// Summary section
|
|
18
18
|
parts.push(`## Summary\n${handoff?.summary ?? "No summary available."}`);
|
|
@@ -39,8 +39,19 @@ export function generatePRDescription(options) {
|
|
|
39
39
|
// Flag draft status with reason
|
|
40
40
|
if (shouldDraft) {
|
|
41
41
|
const reasons = [];
|
|
42
|
-
if (!ralphSatisfied)
|
|
43
|
-
|
|
42
|
+
if (!ralphSatisfied) {
|
|
43
|
+
// urateam#108: distinguish "agent ran, found gaps" from "evaluator
|
|
44
|
+
// crashed". The previous "RALPH found N unmet acceptance criteria"
|
|
45
|
+
// copy lied when N actually counted "RALPH check agent failed: ..."
|
|
46
|
+
// strings, sending reviewers hunting for a non-existent requirement
|
|
47
|
+
// failure.
|
|
48
|
+
if (ralphEvaluationFailed) {
|
|
49
|
+
reasons.push(`RALPH evaluation failed (${ralphEvaluationError ?? "no detail"}) — human review required`);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
reasons.push(`RALPH found ${ralphGaps.length} unmet acceptance criteria`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
44
55
|
if (unresolvedBlockingFindings.length > 0)
|
|
45
56
|
reasons.push(`${unresolvedBlockingFindings.length} blocking review findings remain`);
|
|
46
57
|
parts.push(`> **Draft PR** — ${reasons.join("; ")}. See PR comments for details.`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pr-description.js","sourceRoot":"","sources":["../../src/pipeline/pr-description.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pr-description.js","sourceRoot":"","sources":["../../src/pipeline/pr-description.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/pipeline/runner.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/pipeline/runner.ts"],"names":[],"mappings":"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"}
|
package/dist/pipeline/runner.js
CHANGED
|
@@ -506,6 +506,13 @@ export class PipelineRunner {
|
|
|
506
506
|
let ralphSatisfied = true;
|
|
507
507
|
let ralphGaps = [];
|
|
508
508
|
let ralphSuggestions = [];
|
|
509
|
+
// urateam#108: distinguish "RALPH ran successfully and found N gaps"
|
|
510
|
+
// (ralphSatisfied=false, ralphGaps populated) from "RALPH check agent
|
|
511
|
+
// itself failed" (ralphSatisfied=false, ralphEvaluationFailed=true).
|
|
512
|
+
// These produce different PR-body / comment / notifier copy so reviewers
|
|
513
|
+
// don't waste time hunting for a non-existent failed requirement.
|
|
514
|
+
let ralphEvaluationFailed = false;
|
|
515
|
+
let ralphEvaluationError;
|
|
509
516
|
const effectiveRalphIterations = isFeatureLicensed("deep-review")
|
|
510
517
|
? config.ralphIterations ?? 2
|
|
511
518
|
: Math.min(config.ralphIterations ?? 1, 1);
|
|
@@ -599,6 +606,20 @@ export class PipelineRunner {
|
|
|
599
606
|
ralphSuggestions = [];
|
|
600
607
|
break;
|
|
601
608
|
}
|
|
609
|
+
// Eval-failure path: the check agent itself broke (no parseable
|
|
610
|
+
// output, threw, or exhausted turns). We have NO evidence about
|
|
611
|
+
// gap status; surface that to the human via the PR draft note
|
|
612
|
+
// and skip re-implement (retry on the same conditions almost
|
|
613
|
+
// never recovers, and burns tokens). See urateam#108.
|
|
614
|
+
if (check.evaluationFailed) {
|
|
615
|
+
runLog.warn({ iteration, evaluationError: check.evaluationError }, "RALPH: evaluation failed — drafting PR with eval-failure note instead of re-implementing");
|
|
616
|
+
ralphSatisfied = false;
|
|
617
|
+
ralphEvaluationFailed = true;
|
|
618
|
+
ralphEvaluationError = check.evaluationError;
|
|
619
|
+
ralphGaps = [];
|
|
620
|
+
ralphSuggestions = [];
|
|
621
|
+
break;
|
|
622
|
+
}
|
|
602
623
|
// Track the latest gaps for PR comments if loop exhausts
|
|
603
624
|
ralphGaps = check.gaps;
|
|
604
625
|
ralphSuggestions = check.suggestions;
|
|
@@ -890,13 +911,26 @@ export class PipelineRunner {
|
|
|
890
911
|
runLog.info({ rfIteration }, "RALPH: re-checking requirements after review-fix implement");
|
|
891
912
|
const rfCheck = await checkRequirements(sanitizedIssue, rfHandoffResult, worktreePath);
|
|
892
913
|
ralphSatisfied = rfCheck.satisfied;
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
914
|
+
if (rfCheck.evaluationFailed) {
|
|
915
|
+
ralphEvaluationFailed = true;
|
|
916
|
+
ralphEvaluationError = rfCheck.evaluationError;
|
|
917
|
+
ralphGaps = [];
|
|
918
|
+
ralphSuggestions = [];
|
|
919
|
+
runLog.warn({ rfIteration, evaluationError: rfCheck.evaluationError }, "RALPH: re-check evaluation failed — drafting PR with eval-failure note (urateam#108)");
|
|
897
920
|
}
|
|
898
921
|
else {
|
|
899
|
-
|
|
922
|
+
// Reset in case a prior iteration's eval failed but this
|
|
923
|
+
// re-check ran cleanly.
|
|
924
|
+
ralphEvaluationFailed = false;
|
|
925
|
+
ralphEvaluationError = undefined;
|
|
926
|
+
ralphGaps = rfCheck.gaps;
|
|
927
|
+
ralphSuggestions = rfCheck.suggestions;
|
|
928
|
+
if (rfCheck.satisfied) {
|
|
929
|
+
runLog.info({ rfIteration }, "RALPH: requirements satisfied after review-fix implement");
|
|
930
|
+
}
|
|
931
|
+
else {
|
|
932
|
+
runLog.warn({ rfIteration, gaps: rfCheck.gaps.length }, "RALPH: requirements NOT satisfied after review-fix implement — PR may be created as draft");
|
|
933
|
+
}
|
|
900
934
|
}
|
|
901
935
|
}
|
|
902
936
|
// Update coordination table with latest file changes from review-fix stage
|
|
@@ -1224,6 +1258,8 @@ export class PipelineRunner {
|
|
|
1224
1258
|
shouldDraft,
|
|
1225
1259
|
ralphSatisfied,
|
|
1226
1260
|
ralphGaps,
|
|
1261
|
+
ralphEvaluationFailed,
|
|
1262
|
+
ralphEvaluationError,
|
|
1227
1263
|
unresolvedBlockingFindings,
|
|
1228
1264
|
agentCommits,
|
|
1229
1265
|
});
|
|
@@ -1321,7 +1357,17 @@ export class PipelineRunner {
|
|
|
1321
1357
|
if (shouldDraft && prUrl) {
|
|
1322
1358
|
runLog.info({ prUrl }, "draft PR: adding review comments with gaps and next steps");
|
|
1323
1359
|
const commentParts = [];
|
|
1324
|
-
if (!ralphSatisfied &&
|
|
1360
|
+
if (!ralphSatisfied && ralphEvaluationFailed) {
|
|
1361
|
+
// urateam#108: separate header + copy when the evaluator itself
|
|
1362
|
+
// crashed. The previous "Unmet Acceptance Criteria" header was a
|
|
1363
|
+
// lie — there were zero acceptance criteria checked, the agent
|
|
1364
|
+
// broke before it could check anything.
|
|
1365
|
+
commentParts.push("## RALPH Evaluation Error\n");
|
|
1366
|
+
commentParts.push(`The RALPH requirements-check agent failed to evaluate this PR. Human review is required to confirm all acceptance criteria are met.\n`);
|
|
1367
|
+
commentParts.push(`**Reason:** ${ralphEvaluationError ?? "no detail captured"}\n`);
|
|
1368
|
+
commentParts.push("Common causes: agent exhausted its 6-turn cap on a complex spec, transient SDK error, or agent emitted no parseable JSON. Re-running the issue may succeed.");
|
|
1369
|
+
}
|
|
1370
|
+
else if (!ralphSatisfied && ralphGaps.length > 0) {
|
|
1325
1371
|
commentParts.push("## Unmet Acceptance Criteria (RALPH)\n");
|
|
1326
1372
|
commentParts.push(`RALPH checked ${ralphIterations} time(s) and found the following gaps:\n`);
|
|
1327
1373
|
for (const gap of ralphGaps) {
|
|
@@ -1356,8 +1402,12 @@ export class PipelineRunner {
|
|
|
1356
1402
|
catch (commentErr) {
|
|
1357
1403
|
runLog.warn({ err: commentErr }, "failed to add PR comment for draft — continuing");
|
|
1358
1404
|
}
|
|
1359
|
-
// Notify for human review
|
|
1360
|
-
|
|
1405
|
+
// Notify for human review (urateam#108: don't claim "N unmet
|
|
1406
|
+
// criteria" when N is actually an evaluator-error count).
|
|
1407
|
+
const ralphSummary = ralphEvaluationFailed
|
|
1408
|
+
? "RALPH evaluation failed"
|
|
1409
|
+
: `${ralphGaps.length} unmet acceptance criteria`;
|
|
1410
|
+
await this.notifier.onHumanReviewNeeded?.(run, prUrl, `Draft PR created — ${ralphSummary}, ${unresolvedBlockingFindings.length} blocking findings`);
|
|
1361
1411
|
}
|
|
1362
1412
|
// 6. Auto-merge (skip drafts, unresolved conflicts, or GitLab)
|
|
1363
1413
|
const maxLines = config.autoMergeMaxLines ?? 200;
|