@emiliosp/pi-maestro 0.1.1 → 0.2.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/README.md +5 -5
- package/agents/verifier.md +1 -1
- package/docs/configuration.md +7 -18
- package/docs/subagent-integration.md +15 -14
- package/docs/workflow.md +64 -83
- package/extensions/maestro.ts +12 -12
- package/package.json +6 -5
- package/src/config/loadConfiguration.ts +11 -76
- package/src/maestro/instructions/getMaestroInstructions.ts +2 -2
- package/src/maestro/session/MaestroSessionState.ts +13 -0
- package/src/maestro/status/refreshMaestroStatus.ts +2 -2
- package/src/tools/child/record-verifier-handoff.ts +11 -7
- package/src/tools/child/utils/resolveWorkflowContext.ts +2 -2
- package/src/tools/main/create-spec.ts +2 -2
- package/src/tools/main/mark-spec-ready.ts +4 -4
- package/src/tools/main/resolve-escalation.ts +4 -4
- package/src/tools/main/resolve-findings.ts +3 -3
- package/src/tools/main/{launch-builder.ts → run-builder.ts} +26 -26
- package/src/tools/main/{launch-verifier.ts → run-verifier.ts} +67 -62
- package/src/tools/utils/pi-subagent-delegation.ts +1 -1
- package/src/tools/utils/{resolveToolLaunchContext.ts → resolveToolRunContext.ts} +3 -3
- package/src/workflow/builder/assertBuilderProtocolUnchanged.ts +3 -1
- package/src/workflow/builder/{prepareBuilderLauncher.ts → prepareBuilderRun.ts} +14 -14
- package/src/workflow/state/schema.ts +2 -3
- package/src/workflow/transitions.ts +2 -6
- package/src/workflow/verifier/{prepareVerifierLaunch.ts → prepareVerifierRun.ts} +11 -23
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Objective:
|
|
3
|
-
* Used: When the owner invokes the
|
|
2
|
+
* Objective: Run and validate one foreground verifier pass for the owner session.
|
|
3
|
+
* Used: When the owner invokes the run-verifier tool.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { randomUUID } from 'node:crypto';
|
|
@@ -13,11 +13,12 @@ import { AGENTS } from '#config/schema.ts';
|
|
|
13
13
|
import { getRepositoryStatus } from '#git/repository/getRepositoryStatus.ts';
|
|
14
14
|
import { SPEC_ID_PATTERN } from '#ids/isValidSpecId.ts';
|
|
15
15
|
import type { MaestroPaths } from '#MaestroPaths.ts';
|
|
16
|
+
import maestroSessionState from '#maestro/session/MaestroSessionState.ts';
|
|
16
17
|
import {
|
|
17
18
|
assertDelegationResponse,
|
|
18
19
|
waitForDelegationResponse,
|
|
19
20
|
} from '#tools/utils/pi-subagent-delegation.ts';
|
|
20
|
-
import {
|
|
21
|
+
import { resolveToolRunContext } from '#tools/utils/resolveToolRunContext.ts';
|
|
21
22
|
import { WORKFLOW_ROLES } from '#workflow/roles.ts';
|
|
22
23
|
import { readWorkflowState } from '#workflow/state/readWorkflowState.ts';
|
|
23
24
|
import { WORKFLOW_PHASES, type WorkflowState } from '#workflow/state/schema.ts';
|
|
@@ -27,18 +28,18 @@ import {
|
|
|
27
28
|
} from '#workflow/verifier/completeVerifierPass.ts';
|
|
28
29
|
import { hasProductChanges } from '#workflow/verifier/hasProductChanges.ts';
|
|
29
30
|
import {
|
|
30
|
-
|
|
31
|
-
type
|
|
32
|
-
} from '#workflow/verifier/
|
|
31
|
+
prepareVerifierRun,
|
|
32
|
+
type VerifierRun,
|
|
33
|
+
} from '#workflow/verifier/prepareVerifierRun.ts';
|
|
33
34
|
|
|
34
|
-
export const
|
|
35
|
-
NAME: '
|
|
36
|
-
LABEL: '
|
|
35
|
+
export const RUN_VERIFIER_TOOL = {
|
|
36
|
+
NAME: 'maestro_run_verifier',
|
|
37
|
+
LABEL: 'Run Verifier',
|
|
37
38
|
DESCRIPTION:
|
|
38
|
-
'
|
|
39
|
+
'Run the verifier in the current checkout for a completed builder candidate. The verifier runs in the foreground.',
|
|
39
40
|
} as const;
|
|
40
41
|
|
|
41
|
-
const
|
|
42
|
+
const RunVerifierToolParameters = Type.Object(
|
|
42
43
|
{
|
|
43
44
|
specId: Type.String({ pattern: SPEC_ID_PATTERN.source }),
|
|
44
45
|
},
|
|
@@ -78,7 +79,7 @@ type ProductChangesResult = {
|
|
|
78
79
|
checkpointCommit: string;
|
|
79
80
|
};
|
|
80
81
|
|
|
81
|
-
type
|
|
82
|
+
type VerifierRunResult =
|
|
82
83
|
| CandidateReadyResult
|
|
83
84
|
| FindingsResult
|
|
84
85
|
| ProductChangesResult;
|
|
@@ -86,7 +87,7 @@ type VerifierLaunchResult =
|
|
|
86
87
|
type ReadTerminalVerifierResultInput = {
|
|
87
88
|
paths: MaestroPaths;
|
|
88
89
|
specId: string;
|
|
89
|
-
|
|
90
|
+
run: VerifierRun;
|
|
90
91
|
state: WorkflowState;
|
|
91
92
|
productChanges: boolean;
|
|
92
93
|
};
|
|
@@ -94,7 +95,7 @@ type ReadTerminalVerifierResultInput = {
|
|
|
94
95
|
const readTerminalVerifierResult = async ({
|
|
95
96
|
paths,
|
|
96
97
|
specId,
|
|
97
|
-
|
|
98
|
+
run,
|
|
98
99
|
state,
|
|
99
100
|
productChanges,
|
|
100
101
|
}: ReadTerminalVerifierResultInput): Promise<
|
|
@@ -115,7 +116,7 @@ const readTerminalVerifierResult = async ({
|
|
|
115
116
|
);
|
|
116
117
|
}
|
|
117
118
|
|
|
118
|
-
const repositoryStatus = await getRepositoryStatus(
|
|
119
|
+
const repositoryStatus = await getRepositoryStatus(run.repositoryRoot);
|
|
119
120
|
|
|
120
121
|
if (!repositoryStatus.clean) {
|
|
121
122
|
throw new Error(
|
|
@@ -143,8 +144,8 @@ const readTerminalVerifierResult = async ({
|
|
|
143
144
|
const details = {
|
|
144
145
|
specId,
|
|
145
146
|
revision: state.revision,
|
|
146
|
-
candidateCommit:
|
|
147
|
-
checkpointCommit:
|
|
147
|
+
candidateCommit: run.candidateCommit,
|
|
148
|
+
checkpointCommit: run.checkpointCommit,
|
|
148
149
|
handoff,
|
|
149
150
|
};
|
|
150
151
|
|
|
@@ -158,14 +159,14 @@ const readTerminalVerifierResult = async ({
|
|
|
158
159
|
type ReadVerifierResultInput = {
|
|
159
160
|
paths: MaestroPaths;
|
|
160
161
|
specId: string;
|
|
161
|
-
|
|
162
|
+
run: VerifierRun;
|
|
162
163
|
};
|
|
163
164
|
|
|
164
165
|
const readVerifierResult = async ({
|
|
165
166
|
paths,
|
|
166
167
|
specId,
|
|
167
|
-
|
|
168
|
-
}: ReadVerifierResultInput): Promise<
|
|
168
|
+
run,
|
|
169
|
+
}: ReadVerifierResultInput): Promise<VerifierRunResult> => {
|
|
169
170
|
try {
|
|
170
171
|
const state = await readWorkflowState(paths.getWorkflowPath(specId));
|
|
171
172
|
|
|
@@ -176,8 +177,8 @@ const readVerifierResult = async ({
|
|
|
176
177
|
}
|
|
177
178
|
|
|
178
179
|
const productChanges = await hasProductChanges({
|
|
179
|
-
repositoryRoot:
|
|
180
|
-
candidateCommit:
|
|
180
|
+
repositoryRoot: run.repositoryRoot,
|
|
181
|
+
candidateCommit: run.candidateCommit,
|
|
181
182
|
workflowPath: paths.getWorkflowPath(specId),
|
|
182
183
|
handoffPath: paths.getVerifierHandoffPath(specId),
|
|
183
184
|
});
|
|
@@ -191,8 +192,8 @@ const readVerifierResult = async ({
|
|
|
191
192
|
specId,
|
|
192
193
|
revision: state.revision,
|
|
193
194
|
phase: state.phase,
|
|
194
|
-
candidateCommit:
|
|
195
|
-
checkpointCommit:
|
|
195
|
+
candidateCommit: run.candidateCommit,
|
|
196
|
+
checkpointCommit: run.checkpointCommit,
|
|
196
197
|
};
|
|
197
198
|
}
|
|
198
199
|
|
|
@@ -204,7 +205,7 @@ const readVerifierResult = async ({
|
|
|
204
205
|
return await readTerminalVerifierResult({
|
|
205
206
|
paths,
|
|
206
207
|
specId,
|
|
207
|
-
|
|
208
|
+
run,
|
|
208
209
|
state,
|
|
209
210
|
productChanges,
|
|
210
211
|
});
|
|
@@ -215,7 +216,7 @@ const readVerifierResult = async ({
|
|
|
215
216
|
}
|
|
216
217
|
};
|
|
217
218
|
|
|
218
|
-
const formatVerifierResult = (result:
|
|
219
|
+
const formatVerifierResult = (result: VerifierRunResult): string => {
|
|
219
220
|
if (result.outcome === WORKFLOW_PHASES.CANDIDATE_READY) {
|
|
220
221
|
return `Verifier completed spec ${result.specId}. The workflow is candidate-ready.`;
|
|
221
222
|
}
|
|
@@ -227,44 +228,48 @@ const formatVerifierResult = (result: VerifierLaunchResult): string => {
|
|
|
227
228
|
return `${result.message} The workflow remains verifier-running.`;
|
|
228
229
|
};
|
|
229
230
|
|
|
230
|
-
export const
|
|
231
|
+
export const registerRunVerifierTool = (pi: ExtensionAPI): void => {
|
|
231
232
|
pi.registerTool({
|
|
232
|
-
name:
|
|
233
|
-
label:
|
|
234
|
-
description:
|
|
235
|
-
parameters:
|
|
233
|
+
name: RUN_VERIFIER_TOOL.NAME,
|
|
234
|
+
label: RUN_VERIFIER_TOOL.LABEL,
|
|
235
|
+
description: RUN_VERIFIER_TOOL.DESCRIPTION,
|
|
236
|
+
parameters: RunVerifierToolParameters,
|
|
236
237
|
async execute(toolCallId, { specId }, _signal, _onUpdate, context) {
|
|
237
|
-
const { paths, config } = await
|
|
238
|
-
|
|
239
|
-
const
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
238
|
+
const { paths, config } = await resolveToolRunContext(context.cwd);
|
|
239
|
+
|
|
240
|
+
const run = await prepareVerifierRun({ paths, specId });
|
|
241
|
+
|
|
242
|
+
try {
|
|
243
|
+
const request: SubagentDelegationRequest = {
|
|
244
|
+
requestId: randomUUID(),
|
|
245
|
+
ownerRunId: toolCallId,
|
|
246
|
+
nodeId: WORKFLOW_ROLES.VERIFIER,
|
|
247
|
+
// pi-subagents loads this name from agents/verifier.md through package.json.
|
|
248
|
+
agent: AGENTS.VERIFIER,
|
|
249
|
+
task: `Verify specId "${specId}" at candidate checkpoint "${run.candidateCommit}" in the current checkout "${run.repositoryRoot}". Read all applicable AGENTS.md files before working.`,
|
|
250
|
+
context: 'fresh',
|
|
251
|
+
cwd: run.repositoryRoot,
|
|
252
|
+
model: config.verifier.model,
|
|
253
|
+
thinking: config.verifier.thinking,
|
|
254
|
+
timeoutMs: config.verifier.timeoutMinutes * MILLISECONDS_PER_MINUTE,
|
|
255
|
+
result: { kind: 'text' },
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
const response = await waitForDelegationResponse({
|
|
259
|
+
piEventsBus: pi.events,
|
|
260
|
+
request,
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
assertDelegationResponse(response);
|
|
264
|
+
const result = await readVerifierResult({ paths, specId, run });
|
|
265
|
+
|
|
266
|
+
return {
|
|
267
|
+
content: [{ type: 'text', text: formatVerifierResult(result) }],
|
|
268
|
+
details: result,
|
|
269
|
+
};
|
|
270
|
+
} finally {
|
|
271
|
+
maestroSessionState.clearVerifierCheckpointCommit();
|
|
272
|
+
}
|
|
268
273
|
},
|
|
269
274
|
});
|
|
270
275
|
};
|
|
@@ -8,15 +8,15 @@ import type { MaestroConfig } from '#config/schema.ts';
|
|
|
8
8
|
import { findRepositoryRoot } from '#git/repository/findRepositoryRoot.ts';
|
|
9
9
|
import { MaestroPaths } from '#MaestroPaths.ts';
|
|
10
10
|
|
|
11
|
-
export type
|
|
11
|
+
export type ToolRunContext = {
|
|
12
12
|
repositoryRoot: string;
|
|
13
13
|
config: MaestroConfig;
|
|
14
14
|
paths: MaestroPaths;
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
export const
|
|
17
|
+
export const resolveToolRunContext = async (
|
|
18
18
|
cwd: string,
|
|
19
|
-
): Promise<
|
|
19
|
+
): Promise<ToolRunContext> => {
|
|
20
20
|
const repositoryRoot = await findRepositoryRoot(cwd);
|
|
21
21
|
const config = await loadConfiguration(repositoryRoot);
|
|
22
22
|
|
|
@@ -26,6 +26,8 @@ export async function assertBuilderProtocolUnchanged({
|
|
|
26
26
|
const actualSpecSha256 = await getFileSha256(specPath);
|
|
27
27
|
|
|
28
28
|
if (actualSpecSha256 !== expectedSpecSha256) {
|
|
29
|
-
throw new Error(
|
|
29
|
+
throw new Error(
|
|
30
|
+
`Builder changed spec.md after the run starts: "${specPath}".`,
|
|
31
|
+
);
|
|
30
32
|
}
|
|
31
33
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Objective: Prepare a committed builder
|
|
3
|
-
* Used: Before Maestro
|
|
2
|
+
* Objective: Prepare a committed builder run checkpoint in the current checkout.
|
|
3
|
+
* Used: Before Maestro runs a builder pass.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { rm } from 'node:fs/promises';
|
|
@@ -14,22 +14,22 @@ import { WORKFLOW_EVENTS, WORKFLOW_PHASES } from '#workflow/state/schema.ts';
|
|
|
14
14
|
import { writeWorkflowState } from '#workflow/state/writeWorkflowState.ts';
|
|
15
15
|
import { transitionWorkflow } from '#workflow/transitions.ts';
|
|
16
16
|
|
|
17
|
-
export type
|
|
17
|
+
export type BuilderRun = {
|
|
18
18
|
specId: string;
|
|
19
19
|
revision: number;
|
|
20
20
|
repositoryRoot: string;
|
|
21
21
|
checkpointCommit: string;
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
type
|
|
24
|
+
type AssertBuilderRunBaseInput = {
|
|
25
25
|
paths: MaestroPaths;
|
|
26
26
|
specId: string;
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
async function
|
|
29
|
+
async function assertBuilderRunBase({
|
|
30
30
|
paths,
|
|
31
31
|
specId,
|
|
32
|
-
}:
|
|
32
|
+
}: AssertBuilderRunBaseInput): Promise<void> {
|
|
33
33
|
const state = await readWorkflowState(paths.getWorkflowPath(specId));
|
|
34
34
|
|
|
35
35
|
if (state.specId !== specId) {
|
|
@@ -39,13 +39,13 @@ async function assertBuilderLaunchBase({
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
if (state.phase !== WORKFLOW_PHASES.READY_FOR_BUILDER) {
|
|
42
|
-
throw new Error(`Builder
|
|
42
|
+
throw new Error(`Builder run is not valid from phase "${state.phase}".`);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
const status = await getRepositoryStatus(paths.getRepositoryRoot());
|
|
46
46
|
|
|
47
47
|
if (!status.clean) {
|
|
48
|
-
throw new Error('Builder
|
|
48
|
+
throw new Error('Builder run requires a clean current checkout.');
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
if (!(await pathExists(paths.getSpecFilePath(specId)))) {
|
|
@@ -53,24 +53,24 @@ async function assertBuilderLaunchBase({
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
type
|
|
56
|
+
type PrepareBuilderRunInput = {
|
|
57
57
|
paths: MaestroPaths;
|
|
58
58
|
specId: string;
|
|
59
59
|
};
|
|
60
60
|
|
|
61
|
-
export const
|
|
61
|
+
export const prepareBuilderRun = async ({
|
|
62
62
|
paths,
|
|
63
63
|
specId,
|
|
64
|
-
}:
|
|
64
|
+
}: PrepareBuilderRunInput): Promise<BuilderRun> => {
|
|
65
65
|
const activeSpecId = maestroSessionState.getActiveSpecId();
|
|
66
66
|
|
|
67
67
|
if (activeSpecId !== specId) {
|
|
68
68
|
throw new Error(
|
|
69
|
-
`Builder
|
|
69
|
+
`Builder run requires active Maestro spec "${specId}", found "${activeSpecId ?? 'none'}".`,
|
|
70
70
|
);
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
await
|
|
73
|
+
await assertBuilderRunBase({ paths, specId });
|
|
74
74
|
|
|
75
75
|
const workflowPath = paths.getWorkflowPath(specId);
|
|
76
76
|
const handoffPath = paths.getBuilderHandoffPath(specId);
|
|
@@ -83,7 +83,7 @@ export const prepareBuilderLaunch = async ({
|
|
|
83
83
|
|
|
84
84
|
const nextState = transitionWorkflow({
|
|
85
85
|
state: currentState,
|
|
86
|
-
event: WORKFLOW_EVENTS.
|
|
86
|
+
event: WORKFLOW_EVENTS.RUN_BUILDER,
|
|
87
87
|
});
|
|
88
88
|
|
|
89
89
|
await writeWorkflowState({
|
|
@@ -23,13 +23,12 @@ export const WORKFLOW_PHASES = {
|
|
|
23
23
|
|
|
24
24
|
export const WORKFLOW_EVENTS = {
|
|
25
25
|
MARK_SPEC_READY: 'mark-spec-ready',
|
|
26
|
-
|
|
26
|
+
RUN_BUILDER: 'run-builder',
|
|
27
27
|
OPEN_ESCALATION: 'open-escalation',
|
|
28
28
|
RESOLVE_ESCALATION: 'resolve-escalation',
|
|
29
29
|
BUILDER_FAILED: 'builder-failed',
|
|
30
30
|
BUILDER_DONE: 'builder-done',
|
|
31
|
-
|
|
32
|
-
RETRY_VERIFIER: 'retry-verifier',
|
|
31
|
+
RUN_VERIFIER: 'run-verifier',
|
|
33
32
|
VERIFIER_FOUND_FINDINGS: 'verifier-found-findings',
|
|
34
33
|
VERIFIER_APPROVED: 'verifier-approved',
|
|
35
34
|
REJECT_FINDINGS: 'reject-findings',
|
|
@@ -26,7 +26,7 @@ export const WORKFLOW_TRANSITIONS: Record<WorkflowEvent, WorkflowTransition> = {
|
|
|
26
26
|
],
|
|
27
27
|
to: WORKFLOW_PHASES.READY_FOR_BUILDER,
|
|
28
28
|
},
|
|
29
|
-
[WORKFLOW_EVENTS.
|
|
29
|
+
[WORKFLOW_EVENTS.RUN_BUILDER]: {
|
|
30
30
|
from: [WORKFLOW_PHASES.READY_FOR_BUILDER],
|
|
31
31
|
to: WORKFLOW_PHASES.BUILDER_RUNNING,
|
|
32
32
|
},
|
|
@@ -46,14 +46,10 @@ export const WORKFLOW_TRANSITIONS: Record<WorkflowEvent, WorkflowTransition> = {
|
|
|
46
46
|
from: [WORKFLOW_PHASES.BUILDER_RUNNING],
|
|
47
47
|
to: WORKFLOW_PHASES.READY_FOR_VERIFIER,
|
|
48
48
|
},
|
|
49
|
-
[WORKFLOW_EVENTS.
|
|
49
|
+
[WORKFLOW_EVENTS.RUN_VERIFIER]: {
|
|
50
50
|
from: [WORKFLOW_PHASES.READY_FOR_VERIFIER],
|
|
51
51
|
to: WORKFLOW_PHASES.VERIFIER_RUNNING,
|
|
52
52
|
},
|
|
53
|
-
[WORKFLOW_EVENTS.RETRY_VERIFIER]: {
|
|
54
|
-
from: [WORKFLOW_PHASES.VERIFIER_RUNNING],
|
|
55
|
-
to: WORKFLOW_PHASES.VERIFIER_RUNNING,
|
|
56
|
-
},
|
|
57
53
|
[WORKFLOW_EVENTS.VERIFIER_FOUND_FINDINGS]: {
|
|
58
54
|
from: [WORKFLOW_PHASES.VERIFIER_RUNNING],
|
|
59
55
|
to: WORKFLOW_PHASES.FINDINGS_DECISION,
|
|
@@ -1,21 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Objective: Prepare a committed verifier
|
|
2
|
+
* Objective: Prepare a committed verifier run checkpoint in the current checkout.
|
|
3
3
|
* Used: When Maestro starts a verifier pass.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { rm } from 'node:fs/promises';
|
|
7
7
|
import { createWorkflowCheckpointCommit } from '#git/commits/createWorkflowCheckpointCommit.ts';
|
|
8
|
-
import { getParentCommit } from '#git/history/getParentCommit.ts';
|
|
9
|
-
import { getHeadCommit } from '#git/repository/getHeadCommit.ts';
|
|
10
8
|
import { getRepositoryStatus } from '#git/repository/getRepositoryStatus.ts';
|
|
11
9
|
import type { MaestroPaths } from '#MaestroPaths.ts';
|
|
10
|
+
import maestroSessionState from '#maestro/session/MaestroSessionState.ts';
|
|
12
11
|
import { pathExists } from '#utils/path-exists.ts';
|
|
13
12
|
import { readWorkflowState } from '#workflow/state/readWorkflowState.ts';
|
|
14
13
|
import { WORKFLOW_EVENTS, WORKFLOW_PHASES } from '#workflow/state/schema.ts';
|
|
15
14
|
import { writeWorkflowState } from '#workflow/state/writeWorkflowState.ts';
|
|
16
15
|
import { transitionWorkflow } from '#workflow/transitions.ts';
|
|
17
16
|
|
|
18
|
-
export type
|
|
17
|
+
export type VerifierRun = {
|
|
19
18
|
specId: string;
|
|
20
19
|
repositoryRoot: string;
|
|
21
20
|
candidateCommit: string;
|
|
@@ -23,15 +22,15 @@ export type VerifierLaunch = {
|
|
|
23
22
|
revision: number;
|
|
24
23
|
};
|
|
25
24
|
|
|
26
|
-
type
|
|
25
|
+
type PrepareVerifierRunInput = {
|
|
27
26
|
paths: MaestroPaths;
|
|
28
27
|
specId: string;
|
|
29
28
|
};
|
|
30
29
|
|
|
31
|
-
export const
|
|
30
|
+
export const prepareVerifierRun = async ({
|
|
32
31
|
paths,
|
|
33
32
|
specId,
|
|
34
|
-
}:
|
|
33
|
+
}: PrepareVerifierRunInput): Promise<VerifierRun> => {
|
|
35
34
|
const repositoryRoot = paths.getRepositoryRoot();
|
|
36
35
|
const workflowPath = paths.getWorkflowPath(specId);
|
|
37
36
|
const handoffPath = paths.getVerifierHandoffPath(specId);
|
|
@@ -45,7 +44,7 @@ export const prepareVerifierLaunch = async ({
|
|
|
45
44
|
|
|
46
45
|
if (currentState.phase !== WORKFLOW_PHASES.READY_FOR_VERIFIER) {
|
|
47
46
|
throw new Error(
|
|
48
|
-
`Verifier
|
|
47
|
+
`Verifier run requires ready-for-verifier state, found "${currentState.phase}".`,
|
|
49
48
|
);
|
|
50
49
|
}
|
|
51
50
|
|
|
@@ -53,13 +52,13 @@ export const prepareVerifierLaunch = async ({
|
|
|
53
52
|
|
|
54
53
|
if (!status.clean) {
|
|
55
54
|
throw new Error(
|
|
56
|
-
'Verifier
|
|
55
|
+
'Verifier run requires a committed ready-for-verifier candidate.',
|
|
57
56
|
);
|
|
58
57
|
}
|
|
59
58
|
|
|
60
59
|
const nextState = transitionWorkflow({
|
|
61
60
|
state: currentState,
|
|
62
|
-
event: WORKFLOW_EVENTS.
|
|
61
|
+
event: WORKFLOW_EVENTS.RUN_VERIFIER,
|
|
63
62
|
});
|
|
64
63
|
|
|
65
64
|
const handoffExists = await pathExists(handoffPath);
|
|
@@ -80,28 +79,17 @@ export const prepareVerifierLaunch = async ({
|
|
|
80
79
|
expectedPaths.push(handoffPath);
|
|
81
80
|
}
|
|
82
81
|
|
|
83
|
-
const previousHead = await getHeadCommit(repositoryRoot);
|
|
84
|
-
|
|
85
82
|
const checkpointCommit = await createWorkflowCheckpointCommit({
|
|
86
83
|
repositoryRoot,
|
|
87
84
|
expectedPaths,
|
|
88
85
|
});
|
|
89
86
|
|
|
90
|
-
|
|
91
|
-
repositoryRoot,
|
|
92
|
-
commit: checkpointCommit,
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
if (candidateCommit !== previousHead) {
|
|
96
|
-
throw new Error(
|
|
97
|
-
'Verifier candidate changed while creating its checkpoint.',
|
|
98
|
-
);
|
|
99
|
-
}
|
|
87
|
+
maestroSessionState.setVerifierCheckpointCommit(checkpointCommit);
|
|
100
88
|
|
|
101
89
|
return {
|
|
102
90
|
specId,
|
|
103
91
|
repositoryRoot,
|
|
104
|
-
candidateCommit,
|
|
92
|
+
candidateCommit: checkpointCommit,
|
|
105
93
|
checkpointCommit,
|
|
106
94
|
revision: nextState.revision,
|
|
107
95
|
};
|