@cat-factory/orchestration 0.6.0
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/LICENSE +21 -0
- package/dist/container.d.ts +460 -0
- package/dist/container.d.ts.map +1 -0
- package/dist/container.js +657 -0
- package/dist/container.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/modules/board/BoardService.d.ts +125 -0
- package/dist/modules/board/BoardService.d.ts.map +1 -0
- package/dist/modules/board/BoardService.js +496 -0
- package/dist/modules/board/BoardService.js.map +1 -0
- package/dist/modules/board/board.logic.d.ts +17 -0
- package/dist/modules/board/board.logic.d.ts.map +1 -0
- package/dist/modules/board/board.logic.js +51 -0
- package/dist/modules/board/board.logic.js.map +1 -0
- package/dist/modules/boardScan/BoardScanService.d.ts +35 -0
- package/dist/modules/boardScan/BoardScanService.d.ts.map +1 -0
- package/dist/modules/boardScan/BoardScanService.js +91 -0
- package/dist/modules/boardScan/BoardScanService.js.map +1 -0
- package/dist/modules/boardScan/board-scan.logic.d.ts +10 -0
- package/dist/modules/boardScan/board-scan.logic.d.ts.map +1 -0
- package/dist/modules/boardScan/board-scan.logic.js +26 -0
- package/dist/modules/boardScan/board-scan.logic.js.map +1 -0
- package/dist/modules/bootstrap/BootstrapService.d.ts +114 -0
- package/dist/modules/bootstrap/BootstrapService.d.ts.map +1 -0
- package/dist/modules/bootstrap/BootstrapService.js +516 -0
- package/dist/modules/bootstrap/BootstrapService.js.map +1 -0
- package/dist/modules/clarity/ClarityReviewService.d.ts +48 -0
- package/dist/modules/clarity/ClarityReviewService.d.ts.map +1 -0
- package/dist/modules/clarity/ClarityReviewService.js +63 -0
- package/dist/modules/clarity/ClarityReviewService.js.map +1 -0
- package/dist/modules/clarity/clarity.logic.d.ts +36 -0
- package/dist/modules/clarity/clarity.logic.d.ts.map +1 -0
- package/dist/modules/clarity/clarity.logic.js +98 -0
- package/dist/modules/clarity/clarity.logic.js.map +1 -0
- package/dist/modules/estimation/estimate.logic.d.ts +11 -0
- package/dist/modules/estimation/estimate.logic.d.ts.map +1 -0
- package/dist/modules/estimation/estimate.logic.js +37 -0
- package/dist/modules/estimation/estimate.logic.js.map +1 -0
- package/dist/modules/execution/AgentContextBuilder.d.ts +114 -0
- package/dist/modules/execution/AgentContextBuilder.d.ts.map +1 -0
- package/dist/modules/execution/AgentContextBuilder.js +316 -0
- package/dist/modules/execution/AgentContextBuilder.js.map +1 -0
- package/dist/modules/execution/CompanionController.d.ts +60 -0
- package/dist/modules/execution/CompanionController.d.ts.map +1 -0
- package/dist/modules/execution/CompanionController.js +216 -0
- package/dist/modules/execution/CompanionController.js.map +1 -0
- package/dist/modules/execution/ExecutionService.d.ts +874 -0
- package/dist/modules/execution/ExecutionService.d.ts.map +1 -0
- package/dist/modules/execution/ExecutionService.js +2921 -0
- package/dist/modules/execution/ExecutionService.js.map +1 -0
- package/dist/modules/execution/MergeResolver.d.ts +34 -0
- package/dist/modules/execution/MergeResolver.d.ts.map +1 -0
- package/dist/modules/execution/MergeResolver.js +81 -0
- package/dist/modules/execution/MergeResolver.js.map +1 -0
- package/dist/modules/execution/ReviewGateController.d.ts +163 -0
- package/dist/modules/execution/ReviewGateController.d.ts.map +1 -0
- package/dist/modules/execution/ReviewGateController.js +251 -0
- package/dist/modules/execution/ReviewGateController.js.map +1 -0
- package/dist/modules/execution/TesterController.d.ts +61 -0
- package/dist/modules/execution/TesterController.d.ts.map +1 -0
- package/dist/modules/execution/TesterController.js +215 -0
- package/dist/modules/execution/TesterController.js.map +1 -0
- package/dist/modules/execution/advance.d.ts +84 -0
- package/dist/modules/execution/advance.d.ts.map +1 -0
- package/dist/modules/execution/advance.js +2 -0
- package/dist/modules/execution/advance.js.map +1 -0
- package/dist/modules/execution/artifact-review.logic.d.ts +25 -0
- package/dist/modules/execution/artifact-review.logic.d.ts.map +1 -0
- package/dist/modules/execution/artifact-review.logic.js +39 -0
- package/dist/modules/execution/artifact-review.logic.js.map +1 -0
- package/dist/modules/execution/ci.logic.d.ts +101 -0
- package/dist/modules/execution/ci.logic.d.ts.map +1 -0
- package/dist/modules/execution/ci.logic.js +117 -0
- package/dist/modules/execution/ci.logic.js.map +1 -0
- package/dist/modules/execution/drive.d.ts +47 -0
- package/dist/modules/execution/drive.d.ts.map +1 -0
- package/dist/modules/execution/drive.js +112 -0
- package/dist/modules/execution/drive.js.map +1 -0
- package/dist/modules/execution/gates.d.ts +97 -0
- package/dist/modules/execution/gates.d.ts.map +1 -0
- package/dist/modules/execution/gates.js +2 -0
- package/dist/modules/execution/gates.js.map +1 -0
- package/dist/modules/execution/individualVendors.logic.d.ts +22 -0
- package/dist/modules/execution/individualVendors.logic.d.ts.map +1 -0
- package/dist/modules/execution/individualVendors.logic.js +33 -0
- package/dist/modules/execution/individualVendors.logic.js.map +1 -0
- package/dist/modules/execution/job.logic.d.ts +52 -0
- package/dist/modules/execution/job.logic.d.ts.map +1 -0
- package/dist/modules/execution/job.logic.js +56 -0
- package/dist/modules/execution/job.logic.js.map +1 -0
- package/dist/modules/execution/release.logic.d.ts +43 -0
- package/dist/modules/execution/release.logic.d.ts.map +1 -0
- package/dist/modules/execution/release.logic.js +49 -0
- package/dist/modules/execution/release.logic.js.map +1 -0
- package/dist/modules/execution/retry.logic.d.ts +40 -0
- package/dist/modules/execution/retry.logic.d.ts.map +1 -0
- package/dist/modules/execution/retry.logic.js +83 -0
- package/dist/modules/execution/retry.logic.js.map +1 -0
- package/dist/modules/execution/stepGating.logic.d.ts +15 -0
- package/dist/modules/execution/stepGating.logic.d.ts.map +1 -0
- package/dist/modules/execution/stepGating.logic.js +29 -0
- package/dist/modules/execution/stepGating.logic.js.map +1 -0
- package/dist/modules/execution/stepResolvers.d.ts +41 -0
- package/dist/modules/execution/stepResolvers.d.ts.map +1 -0
- package/dist/modules/execution/stepResolvers.js +2 -0
- package/dist/modules/execution/stepResolvers.js.map +1 -0
- package/dist/modules/execution/tester-infra.logic.d.ts +42 -0
- package/dist/modules/execution/tester-infra.logic.d.ts.map +1 -0
- package/dist/modules/execution/tester-infra.logic.js +46 -0
- package/dist/modules/execution/tester-infra.logic.js.map +1 -0
- package/dist/modules/merge/MergePresetService.d.ts +32 -0
- package/dist/modules/merge/MergePresetService.d.ts.map +1 -0
- package/dist/modules/merge/MergePresetService.js +109 -0
- package/dist/modules/merge/MergePresetService.js.map +1 -0
- package/dist/modules/modelDefaults/ModelDefaultsService.d.ts +22 -0
- package/dist/modules/modelDefaults/ModelDefaultsService.d.ts.map +1 -0
- package/dist/modules/modelDefaults/ModelDefaultsService.js +28 -0
- package/dist/modules/modelDefaults/ModelDefaultsService.js.map +1 -0
- package/dist/modules/notifications/NotificationService.d.ts +74 -0
- package/dist/modules/notifications/NotificationService.d.ts.map +1 -0
- package/dist/modules/notifications/NotificationService.js +131 -0
- package/dist/modules/notifications/NotificationService.js.map +1 -0
- package/dist/modules/observability/LlmObservabilityService.d.ts +121 -0
- package/dist/modules/observability/LlmObservabilityService.d.ts.map +1 -0
- package/dist/modules/observability/LlmObservabilityService.js +140 -0
- package/dist/modules/observability/LlmObservabilityService.js.map +1 -0
- package/dist/modules/observability/observability.logic.d.ts +57 -0
- package/dist/modules/observability/observability.logic.d.ts.map +1 -0
- package/dist/modules/observability/observability.logic.js +186 -0
- package/dist/modules/observability/observability.logic.js.map +1 -0
- package/dist/modules/pipelines/PipelineService.d.ts +54 -0
- package/dist/modules/pipelines/PipelineService.d.ts.map +1 -0
- package/dist/modules/pipelines/PipelineService.js +226 -0
- package/dist/modules/pipelines/PipelineService.js.map +1 -0
- package/dist/modules/pipelines/pipelineShape.d.ts +53 -0
- package/dist/modules/pipelines/pipelineShape.d.ts.map +1 -0
- package/dist/modules/pipelines/pipelineShape.js +74 -0
- package/dist/modules/pipelines/pipelineShape.js.map +1 -0
- package/dist/modules/recurring/RecurringPipelineService.d.ts +76 -0
- package/dist/modules/recurring/RecurringPipelineService.d.ts.map +1 -0
- package/dist/modules/recurring/RecurringPipelineService.js +295 -0
- package/dist/modules/recurring/RecurringPipelineService.js.map +1 -0
- package/dist/modules/recurring/TrackerSettingsService.d.ts +16 -0
- package/dist/modules/recurring/TrackerSettingsService.d.ts.map +1 -0
- package/dist/modules/recurring/TrackerSettingsService.js +30 -0
- package/dist/modules/recurring/TrackerSettingsService.js.map +1 -0
- package/dist/modules/recurring/schedule.logic.d.ts +14 -0
- package/dist/modules/recurring/schedule.logic.d.ts.map +1 -0
- package/dist/modules/recurring/schedule.logic.js +85 -0
- package/dist/modules/recurring/schedule.logic.js.map +1 -0
- package/dist/modules/releaseHealth/ReleaseHealthService.d.ts +38 -0
- package/dist/modules/releaseHealth/ReleaseHealthService.d.ts.map +1 -0
- package/dist/modules/releaseHealth/ReleaseHealthService.js +96 -0
- package/dist/modules/releaseHealth/ReleaseHealthService.js.map +1 -0
- package/dist/modules/requirements/RequirementReviewService.d.ts +48 -0
- package/dist/modules/requirements/RequirementReviewService.d.ts.map +1 -0
- package/dist/modules/requirements/RequirementReviewService.js +83 -0
- package/dist/modules/requirements/RequirementReviewService.js.map +1 -0
- package/dist/modules/requirements/requirements.logic.d.ts +93 -0
- package/dist/modules/requirements/requirements.logic.d.ts.map +1 -0
- package/dist/modules/requirements/requirements.logic.js +203 -0
- package/dist/modules/requirements/requirements.logic.js.map +1 -0
- package/dist/modules/review/IterativeReviewService.d.ts +175 -0
- package/dist/modules/review/IterativeReviewService.d.ts.map +1 -0
- package/dist/modules/review/IterativeReviewService.js +327 -0
- package/dist/modules/review/IterativeReviewService.js.map +1 -0
- package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsService.d.ts +20 -0
- package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsService.d.ts.map +1 -0
- package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsService.js +26 -0
- package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsService.js.map +1 -0
- package/dist/modules/services/ServiceMountService.d.ts +48 -0
- package/dist/modules/services/ServiceMountService.d.ts.map +1 -0
- package/dist/modules/services/ServiceMountService.js +90 -0
- package/dist/modules/services/ServiceMountService.js.map +1 -0
- package/dist/modules/settings/WorkspaceSettingsService.d.ts +22 -0
- package/dist/modules/settings/WorkspaceSettingsService.d.ts.map +1 -0
- package/dist/modules/settings/WorkspaceSettingsService.js +50 -0
- package/dist/modules/settings/WorkspaceSettingsService.js.map +1 -0
- package/package.json +41 -0
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import { assertFound, ConflictError, ValidationError } from '@cat-factory/kernel';
|
|
2
|
+
import { hasNotesToIncorporate } from '../requirements/requirements.logic.js';
|
|
3
|
+
/**
|
|
4
|
+
* Drives the two iterative review gates — `requirements-review` and `clarity-review` — which
|
|
5
|
+
* share the SAME control flow: an inline reviewer LLM raises findings, the run parks on a
|
|
6
|
+
* durable decision-wait, a human answers/dismisses through the dedicated window, an
|
|
7
|
+
* incorporation pass folds the answers into one standardized document, and the reviewer
|
|
8
|
+
* re-reviews it until it converges (or the iteration budget runs out). Only the subject and
|
|
9
|
+
* the persisted document differ; everything structural is shared, so each method below takes
|
|
10
|
+
* a {@link ReviewKind} and is written exactly once. Extracted out of `ExecutionService`; the
|
|
11
|
+
* shared step-graph primitives it calls (the parking gate, the resolved-gate advance, the
|
|
12
|
+
* iteration-cap dispatch, the block/instance writes) stay on the engine and are injected via
|
|
13
|
+
* {@link ReviewGateControllerDeps}.
|
|
14
|
+
*/
|
|
15
|
+
export class ReviewGateController {
|
|
16
|
+
deps;
|
|
17
|
+
constructor(deps) {
|
|
18
|
+
this.deps = deps;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Run a review gate step. When the reviewer isn't wired the step passes through (pipelines
|
|
22
|
+
* run unchanged without the feature). Otherwise it runs the initial reviewer pass: an
|
|
23
|
+
* auto-pass (no findings, or all at/below the task's tolerated severity) advances
|
|
24
|
+
* immediately, recording the findings; anything else parks the run for the dedicated review
|
|
25
|
+
* window to drive the iterative loop. Re-entrant on incorporation: when the human answered
|
|
26
|
+
* the findings and asked to incorporate, the (slow) fold + re-review LLM work runs here in
|
|
27
|
+
* the durable driver instead of in the HTTP request the user is no longer waiting on.
|
|
28
|
+
*/
|
|
29
|
+
async evaluate(kind, workspaceId, instance, step, block, isFinalStep) {
|
|
30
|
+
if (!kind.enabled()) {
|
|
31
|
+
return this.completeStep(workspaceId, instance, step, isFinalStep);
|
|
32
|
+
}
|
|
33
|
+
// Re-entry: the human answered the findings and asked to incorporate. Do the (slow)
|
|
34
|
+
// LLM work here in the durable driver — fold the answers into a document, then
|
|
35
|
+
// re-review it — instead of in the HTTP request that the user is no longer waiting on.
|
|
36
|
+
// `reReview` raises the re-summon notification itself when it finds findings.
|
|
37
|
+
const pending = step.pendingIncorporation;
|
|
38
|
+
if (pending) {
|
|
39
|
+
step.pendingIncorporation = null;
|
|
40
|
+
const review = await this.runIncorporationCycle(kind, workspaceId, block.id, pending.feedback);
|
|
41
|
+
if (review.status === 'incorporated') {
|
|
42
|
+
return this.completeStep(workspaceId, instance, step, isFinalStep);
|
|
43
|
+
}
|
|
44
|
+
// `ready`/`exceeded`: re-park (a fresh decision id) and wait for the human again.
|
|
45
|
+
// At the cap, raise a notification so the three-choice decision is discoverable.
|
|
46
|
+
if (review.status === 'exceeded')
|
|
47
|
+
await this.deps.raiseDecisionRequired(workspaceId, instance);
|
|
48
|
+
return this.deps.parkStepOnDecision(workspaceId, instance, step);
|
|
49
|
+
}
|
|
50
|
+
// Fresh entry: run the initial reviewer pass with the task's preset knobs (shared with
|
|
51
|
+
// the off-path inspector surface). Auto-pass (status `incorporated`) → advance; the
|
|
52
|
+
// findings stay recorded on the review for transparency. `ready`/`exceeded` → park for
|
|
53
|
+
// the dedicated window.
|
|
54
|
+
const review = await this.review(kind, workspaceId, block.id);
|
|
55
|
+
if (review.status === 'incorporated') {
|
|
56
|
+
return this.completeStep(workspaceId, instance, step, isFinalStep);
|
|
57
|
+
}
|
|
58
|
+
if (review.status === 'exceeded')
|
|
59
|
+
await this.deps.raiseDecisionRequired(workspaceId, instance);
|
|
60
|
+
return this.deps.parkStepOnDecision(workspaceId, instance, step);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Fold the human's settled answers into a standardized document and re-review it (one
|
|
64
|
+
* iteration of the loop), emitting the live review-changed event after each phase so an
|
|
65
|
+
* open window/inspector tracks progress. Runs inside the durable driver (see
|
|
66
|
+
* {@link evaluate} re-entry); shared by the no-run inline fallback in {@link incorporate}.
|
|
67
|
+
* Returns the re-reviewed review.
|
|
68
|
+
*/
|
|
69
|
+
async runIncorporationCycle(kind, workspaceId, blockId, feedback) {
|
|
70
|
+
const review = await this.currentReview(kind, workspaceId, blockId);
|
|
71
|
+
// Nothing to fold in (every finding dismissed, no answered replies, no redo
|
|
72
|
+
// feedback) → the requirements stand as-is. Skip the rework + re-review LLM calls
|
|
73
|
+
// and settle the review directly. `markIncorporated` preserves any
|
|
74
|
+
// incorporated document from an earlier iteration, so downstream consumes that
|
|
75
|
+
// prior doc when one exists, else falls back to the original description (nothing
|
|
76
|
+
// was clarified). Mirrors a polling gate's precheck skip.
|
|
77
|
+
if (!hasNotesToIncorporate(review.items, feedback)) {
|
|
78
|
+
const settled = await kind.markIncorporated(workspaceId, review.id);
|
|
79
|
+
await kind.emit(workspaceId, settled);
|
|
80
|
+
return settled;
|
|
81
|
+
}
|
|
82
|
+
const block = assertFound(await this.deps.blockRepository.get(workspaceId, blockId), 'Block', blockId);
|
|
83
|
+
const preset = await this.deps.resolveMergePreset(workspaceId, block);
|
|
84
|
+
await kind.incorporate(workspaceId, blockId, review.id, feedback);
|
|
85
|
+
// The fold is done; flag the SECOND stage (`reviewing`) so the board/window can show
|
|
86
|
+
// "re-reviewing" distinctly from "incorporating" — either of the two LLM calls can be
|
|
87
|
+
// the slow one, so the human needs to know which is currently running.
|
|
88
|
+
const reReviewing = await kind.markReReviewing(workspaceId, review.id);
|
|
89
|
+
await kind.emit(workspaceId, reReviewing);
|
|
90
|
+
const reviewed = await kind.reReview(workspaceId, review.id, preset);
|
|
91
|
+
await kind.emit(workspaceId, reviewed);
|
|
92
|
+
return reviewed;
|
|
93
|
+
}
|
|
94
|
+
/** Finish a review gate step and advance to the next step (or finish the run). */
|
|
95
|
+
async completeStep(workspaceId, instance, step, isFinalStep) {
|
|
96
|
+
this.deps.finishStep(step);
|
|
97
|
+
step.progress = 1;
|
|
98
|
+
step.subtasks = undefined;
|
|
99
|
+
step.approval = null;
|
|
100
|
+
if (isFinalStep) {
|
|
101
|
+
instance.status = 'done';
|
|
102
|
+
await this.deps.finalizeBlock(workspaceId, instance, undefined);
|
|
103
|
+
await this.deps.persistInstance(workspaceId, instance);
|
|
104
|
+
await this.deps.emitInstance(workspaceId, instance);
|
|
105
|
+
await this.deps.stopRunContainer(workspaceId, instance);
|
|
106
|
+
return { kind: 'done' };
|
|
107
|
+
}
|
|
108
|
+
instance.currentStep += 1;
|
|
109
|
+
const next = instance.steps[instance.currentStep];
|
|
110
|
+
if (next)
|
|
111
|
+
this.deps.startStep(next);
|
|
112
|
+
await this.deps.updateBlockProgress(workspaceId, instance, 'in_progress');
|
|
113
|
+
await this.deps.persistInstance(workspaceId, instance);
|
|
114
|
+
await this.deps.emitInstance(workspaceId, instance);
|
|
115
|
+
return { kind: 'continue' };
|
|
116
|
+
}
|
|
117
|
+
/** Resolve a block's current review or throw. */
|
|
118
|
+
async currentReview(kind, workspaceId, blockId) {
|
|
119
|
+
return assertFound(await kind.getForBlock(workspaceId, blockId), kind.entityName, blockId);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Run a fresh reviewer pass over a block, snapshotting the task's merge-preset knobs
|
|
123
|
+
* (iteration budget + tolerated severity) onto the review. Shared by the pipeline gate
|
|
124
|
+
* ({@link evaluate}) and the off-path inspector "Run review" surface, so both honour the
|
|
125
|
+
* task's preset identically.
|
|
126
|
+
*/
|
|
127
|
+
async review(kind, workspaceId, blockId) {
|
|
128
|
+
const block = assertFound(await this.deps.blockRepository.get(workspaceId, blockId), 'Block', blockId);
|
|
129
|
+
const preset = await this.deps.resolveMergePreset(workspaceId, block);
|
|
130
|
+
return kind.review(workspaceId, block, preset);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Incorporate the human's settled answers ASYNCHRONOUSLY. Validates that every finding is
|
|
134
|
+
* answered/dismissed (so the user gets immediate feedback if not), flags the review
|
|
135
|
+
* `incorporating`, records the intent on the parked gate step, and signals the durable
|
|
136
|
+
* driver to wake — which folds the answers and re-reviews in the background (see
|
|
137
|
+
* {@link evaluate} re-entry). Returns at once with the `incorporating` review so the SPA
|
|
138
|
+
* can return the user to the board; they are summoned again only if the re-review yields
|
|
139
|
+
* findings (`ready`) or hits the cap (`exceeded`).
|
|
140
|
+
*
|
|
141
|
+
* No parked run (an off-path inspector review with no active pipeline) → there is no driver
|
|
142
|
+
* to offload to, so the fold + re-review run inline here. That path never had the
|
|
143
|
+
* pipeline-gate freeze this method exists to remove.
|
|
144
|
+
*/
|
|
145
|
+
async incorporate(kind, workspaceId, blockId, feedback) {
|
|
146
|
+
const review = await this.currentReview(kind, workspaceId, blockId);
|
|
147
|
+
const open = review.items.filter((i) => i.status === 'open');
|
|
148
|
+
if (open.length > 0) {
|
|
149
|
+
throw new ValidationError(`Answer or dismiss all ${open.length} remaining item(s) before incorporating`);
|
|
150
|
+
}
|
|
151
|
+
const parked = await this.findParkedStep(kind, workspaceId, blockId);
|
|
152
|
+
if (!parked) {
|
|
153
|
+
// Off-path: no pipeline parked on this review. Do the work inline (it cannot be
|
|
154
|
+
// offloaded to a driver that isn't running) and return the re-reviewed result.
|
|
155
|
+
return this.runIncorporationCycle(kind, workspaceId, blockId, feedback);
|
|
156
|
+
}
|
|
157
|
+
const { instance, step } = parked;
|
|
158
|
+
step.pendingIncorporation = feedback ? { feedback } : {};
|
|
159
|
+
// Re-arm the run BEFORE signalling the driver: the park left it `blocked`, but
|
|
160
|
+
// `advanceInstance` no-ops unless the run is `running`/`paused`, so a woken driver
|
|
161
|
+
// would otherwise return `noop` (and the workflow would end) WITHOUT running the
|
|
162
|
+
// re-entrant incorporate + re-review cycle — leaving the review stuck `incorporating`
|
|
163
|
+
// forever. Mirrors every other resume path (e.g. `advancePastResolvedGate`).
|
|
164
|
+
if (instance.status === 'blocked')
|
|
165
|
+
instance.status = 'running';
|
|
166
|
+
const updated = await kind.markIncorporating(workspaceId, review.id);
|
|
167
|
+
await this.deps.persistInstance(workspaceId, instance);
|
|
168
|
+
await this.deps.emitInstance(workspaceId, instance);
|
|
169
|
+
await kind.emit(workspaceId, updated);
|
|
170
|
+
await this.deps.workRunner.signalDecision(workspaceId, instance.id, step.approval.id, 'incorporate');
|
|
171
|
+
return updated;
|
|
172
|
+
}
|
|
173
|
+
/** Locate the run + gate step a block's review is parked on (or null). */
|
|
174
|
+
async findParkedStep(kind, workspaceId, blockId) {
|
|
175
|
+
const block = await this.deps.blockRepository.get(workspaceId, blockId);
|
|
176
|
+
if (!block?.executionId)
|
|
177
|
+
return null;
|
|
178
|
+
const instance = await this.deps.executionRepository.get(workspaceId, block.executionId);
|
|
179
|
+
if (!instance)
|
|
180
|
+
return null;
|
|
181
|
+
const step = instance.steps.find((s) => s.agentKind === kind.agentKind &&
|
|
182
|
+
s.state === 'waiting_decision' &&
|
|
183
|
+
s.approval?.status === 'pending');
|
|
184
|
+
return step ? { instance, step } : null;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Re-review the incorporated document (one more reviewer pass). On convergence
|
|
188
|
+
* (`incorporated`) the parked run advances; otherwise the window shows the next cycle
|
|
189
|
+
* (`ready`) or the iteration-cap choices (`exceeded`). Only valid once an incorporation
|
|
190
|
+
* has produced a document to re-review (status `merged`).
|
|
191
|
+
*/
|
|
192
|
+
async reReview(kind, workspaceId, blockId) {
|
|
193
|
+
const review = await this.currentReview(kind, workspaceId, blockId);
|
|
194
|
+
if (review.status !== 'merged') {
|
|
195
|
+
throw new ConflictError('Incorporate the answers before re-reviewing');
|
|
196
|
+
}
|
|
197
|
+
const block = assertFound(await this.deps.blockRepository.get(workspaceId, blockId), 'Block', blockId);
|
|
198
|
+
const preset = await this.deps.resolveMergePreset(workspaceId, block);
|
|
199
|
+
const updated = await kind.reReview(workspaceId, review.id, preset);
|
|
200
|
+
if (updated.status === 'incorporated')
|
|
201
|
+
await this.resumeRun(kind, workspaceId, blockId);
|
|
202
|
+
return updated;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Proceed: settle the review (the last incorporated doc, if any, becomes what downstream
|
|
206
|
+
* agents consume) and advance the parked run. Used when every finding is dismissed, or the
|
|
207
|
+
* human proceeds past the iteration cap.
|
|
208
|
+
*/
|
|
209
|
+
async proceed(kind, workspaceId, blockId) {
|
|
210
|
+
const review = await this.currentReview(kind, workspaceId, blockId);
|
|
211
|
+
const updated = await kind.markIncorporated(workspaceId, review.id);
|
|
212
|
+
await this.resumeRun(kind, workspaceId, blockId);
|
|
213
|
+
return updated;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Resolve a review that hit its iteration cap: grant one more round, proceed with the last
|
|
217
|
+
* incorporated doc, or stop the task and reset it to phase zero (the run is cancelled, the
|
|
218
|
+
* block returns to `planned` and is editable again; the review — with its last incorporated
|
|
219
|
+
* doc — survives as a base for the next attempt).
|
|
220
|
+
*/
|
|
221
|
+
async resolveExceeded(kind, workspaceId, blockId, choice) {
|
|
222
|
+
const review = await this.currentReview(kind, workspaceId, blockId);
|
|
223
|
+
await this.deps.dispatchIterationCap(workspaceId, blockId, choice, {
|
|
224
|
+
extraRound: () => kind.grantExtraRound(workspaceId, review.id),
|
|
225
|
+
proceed: () => this.proceed(kind, workspaceId, blockId),
|
|
226
|
+
});
|
|
227
|
+
// Re-read so the caller sees the post-resolution state (the doc survives stop-reset).
|
|
228
|
+
return this.currentReview(kind, workspaceId, blockId);
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Resume a run parked on its review gate: finish the gate step, advance to the next step
|
|
232
|
+
* and wake the durable driver. A no-op when the block has no run parked on a review gate of
|
|
233
|
+
* this kind (e.g. an off-path inspector review with no active pipeline).
|
|
234
|
+
*/
|
|
235
|
+
async resumeRun(kind, workspaceId, blockId) {
|
|
236
|
+
const block = await this.deps.blockRepository.get(workspaceId, blockId);
|
|
237
|
+
if (!block?.executionId)
|
|
238
|
+
return;
|
|
239
|
+
const instance = await this.deps.executionRepository.get(workspaceId, block.executionId);
|
|
240
|
+
if (!instance)
|
|
241
|
+
return;
|
|
242
|
+
const idx = instance.steps.findIndex((s) => s.agentKind === kind.agentKind &&
|
|
243
|
+
s.state === 'waiting_decision' &&
|
|
244
|
+
s.approval?.status === 'pending');
|
|
245
|
+
if (idx === -1)
|
|
246
|
+
return;
|
|
247
|
+
instance.steps[idx].approval.status = 'approved';
|
|
248
|
+
await this.deps.advancePastResolvedGate(workspaceId, instance, idx);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=ReviewGateController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReviewGateController.js","sourceRoot":"","sources":["../../../src/modules/execution/ReviewGateController.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { AgentExecutor, AgentRunResult, Block, BlockRepository, ExecutionInstance, PipelineStep } from '@cat-factory/kernel';
|
|
2
|
+
import type { NotificationService } from '../notifications/NotificationService.js';
|
|
3
|
+
import type { AdvanceResult } from './advance.js';
|
|
4
|
+
import type { AgentContextBuilder } from './AgentContextBuilder.js';
|
|
5
|
+
/** The engine collaborators the Tester gate drives (kept on the engine, injected here). */
|
|
6
|
+
export interface TesterControllerDeps {
|
|
7
|
+
blockRepository: BlockRepository;
|
|
8
|
+
notificationService?: NotificationService;
|
|
9
|
+
agentExecutor: AgentExecutor;
|
|
10
|
+
contextBuilder: AgentContextBuilder;
|
|
11
|
+
/** The task's CI/test attempt budget (from the resolved merge preset). */
|
|
12
|
+
resolveMergePreset: (workspaceId: string, block: Block) => Promise<{
|
|
13
|
+
ciMaxAttempts: number;
|
|
14
|
+
}>;
|
|
15
|
+
/** Reclaim the run's finished container before dispatching the next job. */
|
|
16
|
+
stopRunContainer: (workspaceId: string, instance: ExecutionInstance) => Promise<void>;
|
|
17
|
+
persistInstance: (workspaceId: string, instance: ExecutionInstance) => Promise<void>;
|
|
18
|
+
emitInstance: (workspaceId: string, instance: ExecutionInstance) => Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Drives the Tester gate's fix loop: apply a Tester report to its step (greenlight →
|
|
22
|
+
* advance; withheld + budget left → dispatch the fixer and re-test on its completion;
|
|
23
|
+
* withheld + budget spent / unparseable → fail for a human), and re-dispatch the Tester
|
|
24
|
+
* after a fixer job finishes. Extracted out of `ExecutionService`; the shared engine writes
|
|
25
|
+
* (block reads, container reclaim, instance persistence/emit) stay on the engine and are
|
|
26
|
+
* injected via {@link TesterControllerDeps}.
|
|
27
|
+
*/
|
|
28
|
+
export declare class TesterController {
|
|
29
|
+
private readonly deps;
|
|
30
|
+
constructor(deps: TesterControllerDeps);
|
|
31
|
+
/**
|
|
32
|
+
* Apply a Tester report to its step's gate. Records the report on the step, then:
|
|
33
|
+
* - greenlight → returns `null` so `recordStepResult` finishes + advances;
|
|
34
|
+
* - withheld + budget left → dispatches the `fixer` and parks (re-tested on its
|
|
35
|
+
* completion, see `pollAgentJob`);
|
|
36
|
+
* - withheld + budget spent (or unparseable) → fails the run for human attention.
|
|
37
|
+
*/
|
|
38
|
+
resolveTesterResult(workspaceId: string, instance: ExecutionInstance, step: PipelineStep, result: AgentRunResult): Promise<AdvanceResult | null>;
|
|
39
|
+
/**
|
|
40
|
+
* Re-dispatch the Tester after a Fixer job finished, against the (now-fixed) PR
|
|
41
|
+
* branch. Parks on the fresh Tester job; its report then drives greenlight-or-loop.
|
|
42
|
+
*/
|
|
43
|
+
dispatchTester(workspaceId: string, instance: ExecutionInstance, step: PipelineStep, block: Block): Promise<AdvanceResult>;
|
|
44
|
+
/**
|
|
45
|
+
* Give up on a Tester gate that can't be greenlit. Persists the step (left
|
|
46
|
+
* un-`done`, like the CI gate — never falsely completed), raises a human-actionable
|
|
47
|
+
* `test_failed` notification, and fails the run for human attention. Returns the
|
|
48
|
+
* `job_failed` result the driver propagates.
|
|
49
|
+
*/
|
|
50
|
+
private failTester;
|
|
51
|
+
/** Raise a `test_failed` notification when the Tester gate gives up. */
|
|
52
|
+
private raiseTestFailed;
|
|
53
|
+
/**
|
|
54
|
+
* Dispatch a `fixer` container job for a Tester step that withheld its greenlight:
|
|
55
|
+
* build the agent context with the kind overridden to `fixer` and the Tester's
|
|
56
|
+
* report folded in as resolved context, park on the job, and flip the gate to
|
|
57
|
+
* `fixing`. On the fixer's completion `pollAgentJob` re-dispatches the Tester.
|
|
58
|
+
*/
|
|
59
|
+
private dispatchFixer;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=TesterController.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TesterController.d.ts","sourceRoot":"","sources":["../../../src/modules/execution/TesterController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EAEb,cAAc,EACd,KAAK,EACL,eAAe,EACf,iBAAiB,EACjB,YAAY,EACb,MAAM,qBAAqB,CAAA;AAI5B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAA;AAClF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AA4CnE,2FAA2F;AAC3F,MAAM,WAAW,oBAAoB;IACnC,eAAe,EAAE,eAAe,CAAA;IAChC,mBAAmB,CAAC,EAAE,mBAAmB,CAAA;IACzC,aAAa,EAAE,aAAa,CAAA;IAC5B,cAAc,EAAE,mBAAmB,CAAA;IACnC,0EAA0E;IAC1E,kBAAkB,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC7F,4EAA4E;IAC5E,gBAAgB,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACrF,eAAe,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACpF,YAAY,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAClF;AAED;;;;;;;GAOG;AACH,qBAAa,gBAAgB;IACf,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,EAAE,oBAAoB,EAAI;IAE3D;;;;;;OAMG;IACG,mBAAmB,CACvB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CA+D/B;IAED;;;OAGG;IACG,cAAc,CAClB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,KAAK,GACX,OAAO,CAAC,aAAa,CAAC,CAsBxB;IAED;;;;;OAKG;YACW,UAAU;IAkBxB,wEAAwE;YAC1D,eAAe;IAuB7B;;;;;OAKG;YACW,aAAa;CA0D5B"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { DEFAULT_MERGE_PRESET, isAsyncAgentExecutor } from '@cat-factory/kernel';
|
|
2
|
+
import { parseTestReport } from '@cat-factory/contracts';
|
|
3
|
+
import { FIXER_AGENT_KIND, TESTER_AGENT_KIND } from './ci.logic.js';
|
|
4
|
+
/** Whether a Tester report raised any concern serious enough to block a release. */
|
|
5
|
+
function hasBlockingConcerns(report) {
|
|
6
|
+
return report.concerns.some((c) => c.severity === 'high' || c.severity === 'critical');
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The engine's release verdict for a Tester report: greenlit only when the Tester
|
|
10
|
+
* said so AND it raised no blocking (high/critical) concern. Defensive against a
|
|
11
|
+
* harness that greenlights with open blockers — low/medium concerns are advisory
|
|
12
|
+
* and do not, on their own, withhold the greenlight or loop the fixer.
|
|
13
|
+
*/
|
|
14
|
+
function isGreenlit(report) {
|
|
15
|
+
return report.greenlight === true && !hasBlockingConcerns(report);
|
|
16
|
+
}
|
|
17
|
+
/** One-line, human-readable summary of a Tester report's concerns, for failure messages. */
|
|
18
|
+
function describeTestConcerns(report) {
|
|
19
|
+
if (!report.concerns.length)
|
|
20
|
+
return report.summary || 'No greenlight given.';
|
|
21
|
+
const names = report.concerns
|
|
22
|
+
.map((c) => `${c.title} (${c.severity})`)
|
|
23
|
+
.slice(0, 5)
|
|
24
|
+
.join(', ');
|
|
25
|
+
return `Concerns: ${names}${report.concerns.length > 5 ? ', …' : ''}`;
|
|
26
|
+
}
|
|
27
|
+
/** Render a Tester report as the resolved-context block handed to the fixer. */
|
|
28
|
+
function renderReportForFixer(report) {
|
|
29
|
+
const lines = ['Tester report — fix the concerns below, then the tester will re-run.', ''];
|
|
30
|
+
if (report.summary)
|
|
31
|
+
lines.push(report.summary, '');
|
|
32
|
+
if (report.concerns.length) {
|
|
33
|
+
lines.push('Concerns to fix:');
|
|
34
|
+
for (const c of report.concerns)
|
|
35
|
+
lines.push(`- [${c.severity}] ${c.title}: ${c.detail}`);
|
|
36
|
+
lines.push('');
|
|
37
|
+
}
|
|
38
|
+
const failed = report.outcomes.filter((o) => o.status === 'failed');
|
|
39
|
+
if (failed.length) {
|
|
40
|
+
lines.push('Failed checks:');
|
|
41
|
+
for (const o of failed)
|
|
42
|
+
lines.push(`- ${o.name}${o.detail ? `: ${o.detail}` : ''}`);
|
|
43
|
+
}
|
|
44
|
+
return lines.join('\n').trim();
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Drives the Tester gate's fix loop: apply a Tester report to its step (greenlight →
|
|
48
|
+
* advance; withheld + budget left → dispatch the fixer and re-test on its completion;
|
|
49
|
+
* withheld + budget spent / unparseable → fail for a human), and re-dispatch the Tester
|
|
50
|
+
* after a fixer job finishes. Extracted out of `ExecutionService`; the shared engine writes
|
|
51
|
+
* (block reads, container reclaim, instance persistence/emit) stay on the engine and are
|
|
52
|
+
* injected via {@link TesterControllerDeps}.
|
|
53
|
+
*/
|
|
54
|
+
export class TesterController {
|
|
55
|
+
deps;
|
|
56
|
+
constructor(deps) {
|
|
57
|
+
this.deps = deps;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Apply a Tester report to its step's gate. Records the report on the step, then:
|
|
61
|
+
* - greenlight → returns `null` so `recordStepResult` finishes + advances;
|
|
62
|
+
* - withheld + budget left → dispatches the `fixer` and parks (re-tested on its
|
|
63
|
+
* completion, see `pollAgentJob`);
|
|
64
|
+
* - withheld + budget spent (or unparseable) → fails the run for human attention.
|
|
65
|
+
*/
|
|
66
|
+
async resolveTesterResult(workspaceId, instance, step, result) {
|
|
67
|
+
const block = await this.deps.blockRepository.get(workspaceId, instance.blockId);
|
|
68
|
+
let report = null;
|
|
69
|
+
try {
|
|
70
|
+
report = parseTestReport(result.testReport);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
report = null;
|
|
74
|
+
}
|
|
75
|
+
if (!step.test) {
|
|
76
|
+
const maxAttempts = block
|
|
77
|
+
? (await this.deps.resolveMergePreset(workspaceId, block)).ciMaxAttempts
|
|
78
|
+
: DEFAULT_MERGE_PRESET.ciMaxAttempts;
|
|
79
|
+
step.test = { phase: 'testing', attempts: 0, maxAttempts, lastReport: null };
|
|
80
|
+
}
|
|
81
|
+
if (report)
|
|
82
|
+
step.test.lastReport = report;
|
|
83
|
+
step.test.phase = 'testing';
|
|
84
|
+
step.subtasks = undefined;
|
|
85
|
+
// An unparseable report can't gate a release — fail loudly rather than silently
|
|
86
|
+
// greenlighting or looping forever.
|
|
87
|
+
if (!report) {
|
|
88
|
+
return this.failTester(workspaceId, instance, step, block, result.output ?? 'Tester returned an unparseable report.', 'Tester returned an unparseable test report.', step.test.attempts);
|
|
89
|
+
}
|
|
90
|
+
// The FIRST testing round always loops the fixer when the report flags ANYTHING — any
|
|
91
|
+
// concern (regardless of severity) or a withheld greenlight — so the first batch of
|
|
92
|
+
// findings is always handed to the fixer. From the SECOND round onward the normal
|
|
93
|
+
// threshold applies (`isGreenlit`: a greenlight stands unless a high/critical concern
|
|
94
|
+
// is open; low/medium concerns are advisory). The defensive greenlight+no-blocker
|
|
95
|
+
// check still protects every round against a harness that greenlights with blockers.
|
|
96
|
+
const firstRound = step.test.attempts === 0;
|
|
97
|
+
const accepted = firstRound
|
|
98
|
+
? report.greenlight === true && report.concerns.length === 0
|
|
99
|
+
: isGreenlit(report);
|
|
100
|
+
if (accepted)
|
|
101
|
+
return null;
|
|
102
|
+
// Withheld greenlight: loop the fixer if any budget remains, else give up.
|
|
103
|
+
const executor = this.deps.agentExecutor;
|
|
104
|
+
if (isAsyncAgentExecutor(executor) && block && step.test.attempts < step.test.maxAttempts) {
|
|
105
|
+
// Reclaim the finished Tester container before dispatching the Fixer so the
|
|
106
|
+
// next job boots fresh — the per-run container would otherwise re-attach to the
|
|
107
|
+
// completed Tester job (idempotent dispatch by run id), replaying its result.
|
|
108
|
+
await this.deps.stopRunContainer(workspaceId, instance);
|
|
109
|
+
return this.dispatchFixer(workspaceId, instance, step, block, report);
|
|
110
|
+
}
|
|
111
|
+
// Budget spent (or no async executor to fix with): give up for human attention.
|
|
112
|
+
return this.failTester(workspaceId, instance, step, block, report.summary || 'Tester withheld its greenlight.', `Tester withheld its greenlight after ${step.test.attempts} fix attempt(s). ${describeTestConcerns(report)}`.trim(), step.test.attempts);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Re-dispatch the Tester after a Fixer job finished, against the (now-fixed) PR
|
|
116
|
+
* branch. Parks on the fresh Tester job; its report then drives greenlight-or-loop.
|
|
117
|
+
*/
|
|
118
|
+
async dispatchTester(workspaceId, instance, step, block) {
|
|
119
|
+
const executor = this.deps.agentExecutor;
|
|
120
|
+
if (!isAsyncAgentExecutor(executor)) {
|
|
121
|
+
return { kind: 'job_failed', error: 'No async executor available to run the tester.' };
|
|
122
|
+
}
|
|
123
|
+
const isFinalStep = instance.currentStep === instance.steps.length - 1;
|
|
124
|
+
const context = await this.deps.contextBuilder.buildContext(workspaceId, instance, step, isFinalStep, block);
|
|
125
|
+
const handle = await executor.startJob(context);
|
|
126
|
+
step.jobId = handle.jobId;
|
|
127
|
+
if (handle.model)
|
|
128
|
+
step.model = handle.model;
|
|
129
|
+
step.startingContainer = true;
|
|
130
|
+
step.subtasks = undefined;
|
|
131
|
+
if (step.test)
|
|
132
|
+
step.test.phase = 'testing';
|
|
133
|
+
await this.deps.persistInstance(workspaceId, instance);
|
|
134
|
+
await this.deps.emitInstance(workspaceId, instance);
|
|
135
|
+
return { kind: 'awaiting_job', jobId: step.jobId, stepIndex: instance.currentStep };
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Give up on a Tester gate that can't be greenlit. Persists the step (left
|
|
139
|
+
* un-`done`, like the CI gate — never falsely completed), raises a human-actionable
|
|
140
|
+
* `test_failed` notification, and fails the run for human attention. Returns the
|
|
141
|
+
* `job_failed` result the driver propagates.
|
|
142
|
+
*/
|
|
143
|
+
async failTester(workspaceId, instance, step, block, output, error, attempts) {
|
|
144
|
+
step.output = output;
|
|
145
|
+
await this.deps.persistInstance(workspaceId, instance);
|
|
146
|
+
await this.raiseTestFailed(workspaceId, instance, block, error, attempts);
|
|
147
|
+
// Carry the precise classification (`agent`, not the generic container `job_failed`)
|
|
148
|
+
// and the Tester's own summary to the driver's single `failRun` funnel; failing the
|
|
149
|
+
// run here too would let the driver's second `failRun` clobber it.
|
|
150
|
+
return { kind: 'job_failed', failureKind: 'agent', error, detail: output || undefined };
|
|
151
|
+
}
|
|
152
|
+
/** Raise a `test_failed` notification when the Tester gate gives up. */
|
|
153
|
+
async raiseTestFailed(workspaceId, instance, block, summary, attempts) {
|
|
154
|
+
if (!this.deps.notificationService || !block)
|
|
155
|
+
return;
|
|
156
|
+
await this.deps.notificationService.raise(workspaceId, {
|
|
157
|
+
type: 'test_failed',
|
|
158
|
+
blockId: block.id,
|
|
159
|
+
executionId: instance.id,
|
|
160
|
+
title: `Tests are still failing for "${block.title}"`,
|
|
161
|
+
body: `The Fixer agent tried ${attempts} time(s) but the Tester still won't greenlight. ${summary} ` +
|
|
162
|
+
`Take a look and retry the run once fixed.`,
|
|
163
|
+
payload: {
|
|
164
|
+
...(block.pullRequest?.url ? { prUrl: block.pullRequest.url } : {}),
|
|
165
|
+
pipelineName: instance.pipelineName,
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Dispatch a `fixer` container job for a Tester step that withheld its greenlight:
|
|
171
|
+
* build the agent context with the kind overridden to `fixer` and the Tester's
|
|
172
|
+
* report folded in as resolved context, park on the job, and flip the gate to
|
|
173
|
+
* `fixing`. On the fixer's completion `pollAgentJob` re-dispatches the Tester.
|
|
174
|
+
*/
|
|
175
|
+
async dispatchFixer(workspaceId, instance, step, block, report) {
|
|
176
|
+
const executor = this.deps.agentExecutor;
|
|
177
|
+
if (!isAsyncAgentExecutor(executor)) {
|
|
178
|
+
return { kind: 'job_failed', error: 'No async executor available to fix test failures.' };
|
|
179
|
+
}
|
|
180
|
+
// The fixer pushes its commits onto the implementation PR branch, so it can only
|
|
181
|
+
// run once a coder/integrator step opened one. A Tester-only pipeline (or one whose
|
|
182
|
+
// earlier step never produced a PR) can't be auto-fixed — fail cleanly with the
|
|
183
|
+
// report instead of letting the job-body builder throw out of the advance.
|
|
184
|
+
if (!block.pullRequest?.branch) {
|
|
185
|
+
return this.failTester(workspaceId, instance, step, block, report.summary || 'Tester withheld its greenlight.', `Tester withheld its greenlight and there is no PR branch for the fixer to push to. ${describeTestConcerns(report)}`.trim(), step.test?.attempts ?? 0);
|
|
186
|
+
}
|
|
187
|
+
const isFinalStep = instance.currentStep === instance.steps.length - 1;
|
|
188
|
+
const base = await this.deps.contextBuilder.buildContext(workspaceId, instance, step, isFinalStep, block);
|
|
189
|
+
const context = {
|
|
190
|
+
...base,
|
|
191
|
+
agentKind: FIXER_AGENT_KIND,
|
|
192
|
+
// Hand the fixer the Tester's report (what failed + the concerns) as context.
|
|
193
|
+
priorOutputs: [
|
|
194
|
+
...base.priorOutputs,
|
|
195
|
+
{ agentKind: TESTER_AGENT_KIND, output: renderReportForFixer(report) },
|
|
196
|
+
],
|
|
197
|
+
};
|
|
198
|
+
const handle = await executor.startJob(context);
|
|
199
|
+
step.jobId = handle.jobId;
|
|
200
|
+
if (handle.model)
|
|
201
|
+
step.model = handle.model;
|
|
202
|
+
step.startingContainer = true;
|
|
203
|
+
step.subtasks = undefined;
|
|
204
|
+
step.test = {
|
|
205
|
+
phase: 'fixing',
|
|
206
|
+
attempts: (step.test?.attempts ?? 0) + 1,
|
|
207
|
+
maxAttempts: step.test?.maxAttempts ?? DEFAULT_MERGE_PRESET.ciMaxAttempts,
|
|
208
|
+
lastReport: report,
|
|
209
|
+
};
|
|
210
|
+
await this.deps.persistInstance(workspaceId, instance);
|
|
211
|
+
await this.deps.emitInstance(workspaceId, instance);
|
|
212
|
+
return { kind: 'awaiting_job', jobId: step.jobId, stepIndex: instance.currentStep };
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=TesterController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TesterController.js","sourceRoot":"","sources":["../../../src/modules/execution/TesterController.ts"],"names":[],"mappings":"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"}
|