voratiq 0.1.0-beta.21 → 0.1.0-beta.22
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 +18 -22
- package/dist/agents/launch/chat.d.ts +3 -1
- package/dist/agents/launch/chat.js +2 -0
- package/dist/bin.js +28 -7
- package/dist/cli/auto.js +1 -0
- package/dist/cli/contract.d.ts +26 -17
- package/dist/cli/contract.js +3 -1
- package/dist/cli/doctor.d.ts +12 -0
- package/dist/cli/doctor.js +115 -0
- package/dist/cli/list.js +4 -1
- package/dist/cli/operator-envelope.d.ts +19 -6
- package/dist/cli/operator-envelope.js +61 -1
- package/dist/cli/run.js +2 -0
- package/dist/cli/verify.d.ts +1 -1
- package/dist/cli/verify.js +48 -9
- package/dist/commands/auto/command.d.ts +1 -0
- package/dist/commands/auto/command.js +22 -12
- package/dist/commands/auto/errors.js +1 -1
- package/dist/commands/doctor/agents.d.ts +5 -0
- package/dist/commands/{init → doctor}/agents.js +37 -19
- package/dist/commands/doctor/command.d.ts +22 -0
- package/dist/commands/doctor/command.js +99 -0
- package/dist/commands/doctor/environment.d.ts +2 -0
- package/dist/commands/{init → doctor}/environment.js +38 -6
- package/dist/commands/{init/types.d.ts → doctor/fix-types.d.ts} +30 -9
- package/dist/commands/doctor/fix.d.ts +2 -0
- package/dist/commands/{init/command.js → doctor/fix.js} +106 -10
- package/dist/commands/doctor/reconcile.d.ts +2 -0
- package/dist/commands/doctor/reconcile.js +101 -0
- package/dist/commands/interactive/lifecycle.d.ts +2 -0
- package/dist/commands/interactive/lifecycle.js +8 -0
- package/dist/commands/list/command.d.ts +1 -0
- package/dist/commands/list/command.js +211 -352
- package/dist/commands/list/normalization.d.ts +56 -0
- package/dist/commands/list/normalization.js +317 -0
- package/dist/commands/message/command.d.ts +2 -1
- package/dist/commands/message/command.js +35 -14
- package/dist/commands/message/errors.d.ts +12 -3
- package/dist/commands/message/errors.js +19 -3
- package/dist/commands/reduce/command.js +16 -17
- package/dist/commands/reduce/errors.d.ts +2 -2
- package/dist/commands/reduce/errors.js +3 -3
- package/dist/commands/reduce/targets.js +11 -2
- package/dist/commands/root-launcher/command.js +12 -6
- package/dist/commands/run/command.d.ts +1 -0
- package/dist/commands/run/command.js +4 -1
- package/dist/commands/run/record-init.d.ts +2 -0
- package/dist/commands/run/record-init.js +2 -1
- package/dist/commands/run/spec-provenance.d.ts +37 -0
- package/dist/commands/run/spec-provenance.js +384 -0
- package/dist/commands/run/validation.d.ts +4 -0
- package/dist/commands/run/validation.js +25 -62
- package/dist/commands/spec/command.js +19 -6
- package/dist/commands/spec/errors.d.ts +5 -0
- package/dist/commands/spec/errors.js +9 -0
- package/dist/commands/verify/agents.d.ts +4 -2
- package/dist/commands/verify/agents.js +4 -11
- package/dist/commands/verify/command.js +15 -5
- package/dist/commands/verify/errors.d.ts +12 -0
- package/dist/commands/verify/errors.js +22 -0
- package/dist/commands/verify/targets.js +108 -12
- package/dist/competition/shared/preflight.d.ts +1 -1
- package/dist/competition/shared/preflight.js +15 -2
- package/dist/contracts/list.d.ts +129 -149
- package/dist/contracts/list.js +47 -99
- package/dist/domain/interactive/persistence/adapter.d.ts +23 -0
- package/dist/domain/interactive/persistence/adapter.js +42 -0
- package/dist/domain/message/model/types.d.ts +32 -0
- package/dist/domain/message/model/types.js +25 -0
- package/dist/domain/reduce/competition/adapter.js +21 -7
- package/dist/domain/reduce/competition/finalize.d.ts +7 -0
- package/dist/domain/reduce/competition/finalize.js +19 -0
- package/dist/domain/reduce/model/types.d.ts +3 -3
- package/dist/domain/run/competition/agents/artifacts.js +4 -2
- package/dist/domain/run/competition/errors.d.ts +1 -1
- package/dist/domain/run/competition/errors.js +4 -7
- package/dist/domain/run/model/types.d.ts +384 -0
- package/dist/domain/run/model/types.js +87 -0
- package/dist/domain/spec/competition/adapter.d.ts +1 -0
- package/dist/domain/spec/competition/adapter.js +6 -1
- package/dist/domain/spec/model/types.d.ts +3 -0
- package/dist/domain/spec/model/types.js +5 -0
- package/dist/domain/verify/competition/finalize.d.ts +9 -0
- package/dist/domain/verify/competition/finalize.js +22 -3
- package/dist/domain/verify/model/types.d.ts +2 -2
- package/dist/interactive/providers/mcp.d.ts +1 -0
- package/dist/interactive/providers/mcp.js +45 -7
- package/dist/interactive/substrate.js +20 -3
- package/dist/mcp/server.js +26 -9
- package/dist/policy/verification.js +18 -1
- package/dist/preflight/agents.d.ts +24 -0
- package/dist/preflight/agents.js +71 -0
- package/dist/preflight/environment.d.ts +6 -0
- package/dist/preflight/environment.js +17 -0
- package/dist/preflight/formatting.d.ts +5 -0
- package/dist/preflight/formatting.js +20 -0
- package/dist/preflight/index.d.ts +2 -0
- package/dist/preflight/index.js +5 -9
- package/dist/preflight/operator.d.ts +32 -0
- package/dist/preflight/operator.js +40 -0
- package/dist/preflight/settings.d.ts +2 -0
- package/dist/preflight/settings.js +17 -0
- package/dist/render/transcripts/interactive.d.ts +16 -0
- package/dist/render/transcripts/interactive.js +42 -0
- package/dist/render/transcripts/list.d.ts +41 -0
- package/dist/render/transcripts/list.js +152 -3
- package/dist/render/transcripts/message.d.ts +2 -1
- package/dist/render/transcripts/message.js +19 -20
- package/dist/render/transcripts/reduce.d.ts +1 -0
- package/dist/render/transcripts/reduce.js +21 -21
- package/dist/render/transcripts/root-launcher.js +2 -12
- package/dist/render/transcripts/run.d.ts +3 -0
- package/dist/render/transcripts/run.js +30 -4
- package/dist/render/transcripts/spec.js +5 -8
- package/dist/render/transcripts/verify.d.ts +5 -3
- package/dist/render/transcripts/verify.js +44 -31
- package/dist/render/utils/duration.d.ts +5 -0
- package/dist/render/utils/duration.js +6 -0
- package/dist/render/utils/runs.d.ts +1 -0
- package/dist/render/utils/runs.js +1 -0
- package/dist/render/utils/transcript-shell.d.ts +2 -1
- package/dist/render/utils/transcript-shell.js +19 -6
- package/dist/utils/errors.d.ts +2 -1
- package/dist/utils/errors.js +3 -1
- package/dist/utils/git.d.ts +1 -1
- package/dist/utils/git.js +25 -2
- package/dist/utils/list-target.d.ts +4 -0
- package/dist/utils/list-target.js +35 -0
- package/dist/utils/terminal.d.ts +1 -0
- package/dist/utils/terminal.js +11 -0
- package/dist/workspace/chat/artifacts.d.ts +7 -0
- package/dist/workspace/chat/artifacts.js +94 -3
- package/dist/workspace/errors.js +2 -2
- package/dist/workspace/managed-state.d.ts +32 -0
- package/dist/workspace/managed-state.js +103 -0
- package/dist/workspace/setup.js +66 -2
- package/dist/workspace/shim.d.ts +1 -0
- package/dist/workspace/shim.js +3 -3
- package/dist/workspace/structure.d.ts +1 -0
- package/dist/workspace/structure.js +1 -0
- package/package.json +2 -2
- package/dist/cli/init.d.ts +0 -15
- package/dist/cli/init.js +0 -70
- package/dist/commands/init/agents.d.ts +0 -4
- package/dist/commands/init/command.d.ts +0 -2
- package/dist/commands/init/environment.d.ts +0 -2
- package/dist/render/transcripts/init.d.ts +0 -7
- package/dist/render/transcripts/init.js +0 -83
- /package/dist/commands/{init/types.js → doctor/fix-types.js} +0 -0
|
@@ -1,86 +1,49 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
2
|
-
import { verifyAgentProviders } from "../../agents/runtime/auth.js";
|
|
3
|
-
import { loadAgentCatalogDiagnostics } from "../../configs/agents/loader.js";
|
|
4
|
-
import { EnvironmentConfigParseError, MissingEnvironmentConfigError, } from "../../configs/environment/errors.js";
|
|
5
|
-
import { DEFAULT_ENVIRONMENT_FILE_DISPLAY, loadEnvironmentConfig, } from "../../configs/environment/loader.js";
|
|
6
|
-
import { loadRepoSettings } from "../../configs/settings/loader.js";
|
|
7
1
|
import { NoAgentsEnabledError, RunPreflightError, } from "../../domain/run/competition/errors.js";
|
|
8
2
|
import { RunOptionValidationError } from "../../domain/run/model/errors.js";
|
|
9
|
-
import {
|
|
3
|
+
import { loadOperatorEnvironment } from "../../preflight/environment.js";
|
|
4
|
+
import { prepareConfiguredOperatorReadiness } from "../../preflight/operator.js";
|
|
10
5
|
import { getHeadRevision } from "../../utils/git.js";
|
|
11
|
-
import { WorkspaceMissingEntryError } from "../../workspace/errors.js";
|
|
12
6
|
import { resolveEffectiveMaxParallel } from "../shared/max-parallel.js";
|
|
7
|
+
import { loadRunSpecInput } from "./spec-provenance.js";
|
|
13
8
|
/**
|
|
14
9
|
* Validate command parameters, load spec, and prepare execution prerequisites.
|
|
15
10
|
*/
|
|
16
11
|
export async function validateAndPrepare(input) {
|
|
17
|
-
const { root, specAbsolutePath, resolvedAgentIds, maxParallel: requestedMaxParallel, } = input;
|
|
12
|
+
const { root, specAbsolutePath, specDisplayPath, specsFilePath, resolvedAgentIds, maxParallel: requestedMaxParallel, } = input;
|
|
18
13
|
if (requestedMaxParallel !== undefined &&
|
|
19
14
|
(!Number.isInteger(requestedMaxParallel) || requestedMaxParallel <= 0)) {
|
|
20
15
|
throw new RunOptionValidationError("maxParallel", "must be a positive integer");
|
|
21
16
|
}
|
|
22
|
-
const specContent = await
|
|
17
|
+
const { specContent, specTarget } = await loadRunSpecInput({
|
|
18
|
+
root,
|
|
19
|
+
specAbsolutePath,
|
|
20
|
+
specDisplayPath: specDisplayPath ?? specAbsolutePath,
|
|
21
|
+
specsFilePath,
|
|
22
|
+
});
|
|
23
23
|
const baseRevisionSha = await getHeadRevision(root);
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const agentDiagnostics = loadAgentCatalogDiagnostics({ root });
|
|
32
|
-
preflightIssues.push(...agentDiagnostics.issues.filter((issue) => selectedAgentIds.has(issue.agentId)));
|
|
33
|
-
const catalogById = new Map(agentDiagnostics.catalog.map((agent) => [agent.id, agent]));
|
|
34
|
-
agents = resolvedAgentIds.flatMap((agentId) => {
|
|
35
|
-
const agent = catalogById.get(agentId);
|
|
36
|
-
return agent ? [agent] : [];
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
const agentDiagnostics = loadAgentCatalogDiagnostics({ root });
|
|
41
|
-
const enabledAgents = agentDiagnostics.enabledAgents;
|
|
42
|
-
if (enabledAgents.length === 0) {
|
|
43
|
-
throw new NoAgentsEnabledError();
|
|
44
|
-
}
|
|
45
|
-
preflightIssues.push(...agentDiagnostics.issues);
|
|
46
|
-
agents = agentDiagnostics.catalog;
|
|
47
|
-
}
|
|
48
|
-
try {
|
|
49
|
-
loadRepoSettings({ root });
|
|
50
|
-
}
|
|
51
|
-
catch (error) {
|
|
52
|
-
preflightIssues.push({
|
|
53
|
-
agentId: "settings",
|
|
54
|
-
message: toErrorMessage(error),
|
|
55
|
-
});
|
|
24
|
+
const preflight = await prepareConfiguredOperatorReadiness({
|
|
25
|
+
root,
|
|
26
|
+
resolvedAgentIds,
|
|
27
|
+
includeEnvironment: false,
|
|
28
|
+
});
|
|
29
|
+
if (preflight.noAgentsEnabled) {
|
|
30
|
+
throw new NoAgentsEnabledError();
|
|
56
31
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
id: agent.id,
|
|
60
|
-
provider: agent.provider,
|
|
61
|
-
})));
|
|
62
|
-
preflightIssues.push(...providerIssues);
|
|
63
|
-
if (preflightIssues.length > 0) {
|
|
64
|
-
throw new RunPreflightError(preflightIssues, preProviderIssueCount === 0 ? [] : undefined);
|
|
32
|
+
if (preflight.issues.length > 0) {
|
|
33
|
+
throw new RunPreflightError(preflight.issues, preflight.preProviderIssueCount);
|
|
65
34
|
}
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (error instanceof MissingEnvironmentConfigError ||
|
|
72
|
-
error instanceof EnvironmentConfigParseError) {
|
|
73
|
-
throw new WorkspaceMissingEntryError(DEFAULT_ENVIRONMENT_FILE_DISPLAY);
|
|
74
|
-
}
|
|
75
|
-
throw error;
|
|
76
|
-
}
|
|
77
|
-
})();
|
|
35
|
+
const agents = preflight.agents;
|
|
36
|
+
const environment = loadOperatorEnvironment({
|
|
37
|
+
root,
|
|
38
|
+
errorMode: "workspace-missing",
|
|
39
|
+
});
|
|
78
40
|
const effectiveMaxParallel = resolveEffectiveMaxParallel({
|
|
79
41
|
competitorCount: agents.length,
|
|
80
42
|
requestedMaxParallel,
|
|
81
43
|
});
|
|
82
44
|
return {
|
|
83
45
|
specContent,
|
|
46
|
+
specTarget,
|
|
84
47
|
baseRevisionSha,
|
|
85
48
|
agents,
|
|
86
49
|
effectiveMaxParallel,
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import { executeCompetitionWithAdapter } from "../../competition/command-adapter.js";
|
|
2
2
|
import { AgentNotFoundError } from "../../configs/agents/errors.js";
|
|
3
|
-
import { loadEnvironmentConfig } from "../../configs/environment/loader.js";
|
|
4
3
|
import { buildLifecycleStartFields, buildOperationLifecycleCompleteFields, } from "../../domain/shared/lifecycle.js";
|
|
5
4
|
import { createSpecCompetitionAdapter, } from "../../domain/spec/competition/adapter.js";
|
|
6
5
|
import { deriveSpecStatusFromAgents, } from "../../domain/spec/model/types.js";
|
|
7
6
|
import { appendSpecRecord, finalizeSpecRecord, flushSpecRecordBuffer, rewriteSpecRecord, } from "../../domain/spec/persistence/adapter.js";
|
|
8
7
|
import { buildPersistedExtraContextFields } from "../../extra-context/contract.js";
|
|
8
|
+
import { loadOperatorEnvironment } from "../../preflight/environment.js";
|
|
9
|
+
import { prepareConfiguredOperatorReadiness } from "../../preflight/operator.js";
|
|
9
10
|
import { toErrorMessage } from "../../utils/errors.js";
|
|
10
11
|
import { getHeadRevision } from "../../utils/git.js";
|
|
11
12
|
import { resolveEffectiveMaxParallel } from "../shared/max-parallel.js";
|
|
12
13
|
import { resolveStageCompetitors } from "../shared/resolve-stage-competitors.js";
|
|
13
14
|
import { generateSessionId } from "../shared/session-id.js";
|
|
14
|
-
import { SpecAgentNotFoundError, SpecGenerationFailedError } from "./errors.js";
|
|
15
|
+
import { SpecAgentNotFoundError, SpecGenerationFailedError, SpecPreflightError, } from "./errors.js";
|
|
15
16
|
export async function executeSpecCommand(input) {
|
|
16
17
|
const { root, specsFilePath, description, agentIds: cliAgentIds, profileName, maxParallel: requestedMaxParallel, title: providedTitle, extraContextFiles = [], onStatus, renderer, } = input;
|
|
17
|
-
let
|
|
18
|
+
let resolvedAgentIds;
|
|
18
19
|
try {
|
|
19
20
|
const normalizedCliIds = cliAgentIds && cliAgentIds.length > 0 ? [...cliAgentIds] : undefined;
|
|
20
21
|
const resolution = resolveStageCompetitors({
|
|
@@ -22,9 +23,10 @@ export async function executeSpecCommand(input) {
|
|
|
22
23
|
stageId: "spec",
|
|
23
24
|
cliAgentIds: normalizedCliIds,
|
|
24
25
|
profileName,
|
|
26
|
+
includeDefinitions: false,
|
|
25
27
|
});
|
|
26
|
-
|
|
27
|
-
if (
|
|
28
|
+
resolvedAgentIds = resolution.agentIds;
|
|
29
|
+
if (resolvedAgentIds.length === 0) {
|
|
28
30
|
throw new SpecGenerationFailedError(["Spec agent resolution failed."]);
|
|
29
31
|
}
|
|
30
32
|
}
|
|
@@ -34,7 +36,16 @@ export async function executeSpecCommand(input) {
|
|
|
34
36
|
}
|
|
35
37
|
throw error;
|
|
36
38
|
}
|
|
37
|
-
const
|
|
39
|
+
const preflight = await prepareConfiguredOperatorReadiness({
|
|
40
|
+
root,
|
|
41
|
+
resolvedAgentIds,
|
|
42
|
+
includeEnvironment: false,
|
|
43
|
+
});
|
|
44
|
+
if (preflight.issues.length > 0) {
|
|
45
|
+
throw new SpecPreflightError(preflight.issues, preflight.preProviderIssueCount);
|
|
46
|
+
}
|
|
47
|
+
const competitors = preflight.agents;
|
|
48
|
+
const environment = loadOperatorEnvironment({ root });
|
|
38
49
|
const effectiveMaxParallel = resolveEffectiveMaxParallel({
|
|
39
50
|
competitorCount: competitors.length,
|
|
40
51
|
requestedMaxParallel,
|
|
@@ -251,6 +262,7 @@ async function persistSpecAgentCompletion(options) {
|
|
|
251
262
|
...completeFields,
|
|
252
263
|
outputPath: result.outputPath,
|
|
253
264
|
dataPath: result.dataPath,
|
|
265
|
+
contentHash: result.contentHash,
|
|
254
266
|
tokenUsage: result.tokenUsage,
|
|
255
267
|
error: null,
|
|
256
268
|
};
|
|
@@ -317,6 +329,7 @@ function mapExecutionResultsToSpecAgents(executionResults, startedAt) {
|
|
|
317
329
|
status: "succeeded",
|
|
318
330
|
outputPath: result.outputPath,
|
|
319
331
|
dataPath: result.dataPath,
|
|
332
|
+
contentHash: result.contentHash,
|
|
320
333
|
tokenUsage: result.tokenUsage,
|
|
321
334
|
};
|
|
322
335
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CliError } from "../../cli/errors.js";
|
|
2
|
+
import type { PreflightIssue } from "../../competition/shared/preflight.js";
|
|
2
3
|
export declare class SpecError extends CliError {
|
|
3
4
|
constructor(headline: string, detailLines?: readonly string[], hintLines?: readonly string[]);
|
|
4
5
|
}
|
|
@@ -9,3 +10,7 @@ export declare class SpecAgentNotFoundError extends SpecError {
|
|
|
9
10
|
export declare class SpecGenerationFailedError extends SpecError {
|
|
10
11
|
constructor(detailLines?: readonly string[]);
|
|
11
12
|
}
|
|
13
|
+
export declare class SpecPreflightError extends SpecError {
|
|
14
|
+
readonly issues: readonly PreflightIssue[];
|
|
15
|
+
constructor(issues: readonly PreflightIssue[], preProviderIssueCount: number);
|
|
16
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CliError } from "../../cli/errors.js";
|
|
2
|
+
import { formatOperatorPreflightIssueLines, resolveOperatorPreflightHintLines, } from "../../preflight/formatting.js";
|
|
2
3
|
export class SpecError extends CliError {
|
|
3
4
|
constructor(headline, detailLines = [], hintLines = []) {
|
|
4
5
|
super(headline, detailLines, hintLines);
|
|
@@ -21,3 +22,11 @@ export class SpecGenerationFailedError extends SpecError {
|
|
|
21
22
|
this.name = "SpecGenerationFailedError";
|
|
22
23
|
}
|
|
23
24
|
}
|
|
25
|
+
export class SpecPreflightError extends SpecError {
|
|
26
|
+
issues;
|
|
27
|
+
constructor(issues, preProviderIssueCount) {
|
|
28
|
+
super("Preflight failed. Aborting specification generation.", formatOperatorPreflightIssueLines(issues), resolveOperatorPreflightHintLines(issues, preProviderIssueCount) ?? []);
|
|
29
|
+
this.issues = Array.from(issues);
|
|
30
|
+
this.name = "SpecPreflightError";
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -4,5 +4,7 @@ export declare function resolveVerificationAgents(options: {
|
|
|
4
4
|
root: string;
|
|
5
5
|
agentOverrideFlag?: string;
|
|
6
6
|
profileName?: string;
|
|
7
|
-
}):
|
|
8
|
-
|
|
7
|
+
}): {
|
|
8
|
+
readonly agentIds: readonly string[];
|
|
9
|
+
readonly competitors: readonly AgentDefinition[];
|
|
10
|
+
};
|
|
@@ -1,29 +1,22 @@
|
|
|
1
|
-
import { verifyAgentProviders } from "../../agents/runtime/auth.js";
|
|
2
1
|
import { AgentNotFoundError } from "../../configs/agents/errors.js";
|
|
3
2
|
import { resolveStageCompetitors } from "../shared/resolve-stage-competitors.js";
|
|
3
|
+
import { VerifyAgentNotFoundError } from "./errors.js";
|
|
4
4
|
export function resolveVerificationAgents(options) {
|
|
5
5
|
const { agentIds, root, agentOverrideFlag, profileName } = options;
|
|
6
6
|
try {
|
|
7
|
-
|
|
7
|
+
return resolveStageCompetitors({
|
|
8
8
|
root,
|
|
9
9
|
stageId: "verify",
|
|
10
10
|
cliAgentIds: agentIds,
|
|
11
11
|
cliOverrideFlag: agentOverrideFlag,
|
|
12
12
|
profileName,
|
|
13
|
+
includeDefinitions: false,
|
|
13
14
|
});
|
|
14
|
-
return [...resolution.competitors];
|
|
15
15
|
}
|
|
16
16
|
catch (error) {
|
|
17
17
|
if (error instanceof AgentNotFoundError) {
|
|
18
|
-
throw new
|
|
18
|
+
throw new VerifyAgentNotFoundError(error.agentId);
|
|
19
19
|
}
|
|
20
20
|
throw error;
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
-
export async function assertVerifierPreflight(agents) {
|
|
24
|
-
const providerIssues = await verifyAgentProviders(agents.map((agent) => ({ id: agent.id, provider: agent.provider })));
|
|
25
|
-
if (providerIssues.length > 0) {
|
|
26
|
-
const detail = providerIssues.map((issue) => issue.message).join("; ");
|
|
27
|
-
throw new Error(`Verifier preflight failed: ${detail}`);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { teardownSessionAuth } from "../../agents/runtime/registry.js";
|
|
2
2
|
import { createTeardownController } from "../../competition/shared/teardown.js";
|
|
3
|
-
import { loadEnvironmentConfig } from "../../configs/environment/loader.js";
|
|
4
3
|
import { loadVerificationConfig } from "../../configs/verification/loader.js";
|
|
5
4
|
import { buildBlindedAliasMap } from "../../domain/verify/competition/blinding.js";
|
|
6
5
|
import { deriveVerificationStatusFromMethods, maybePersistSelectedSpecPath, } from "../../domain/verify/competition/finalize.js";
|
|
@@ -9,11 +8,14 @@ import { executeAndPersistRubricMethods } from "../../domain/verify/competition/
|
|
|
9
8
|
import { createVerificationRecordMutators } from "../../domain/verify/model/mutators.js";
|
|
10
9
|
import { appendVerificationRecord, flushVerificationRecordBuffer, } from "../../domain/verify/persistence/adapter.js";
|
|
11
10
|
import { buildPersistedExtraContextFields } from "../../extra-context/contract.js";
|
|
11
|
+
import { loadOperatorEnvironment } from "../../preflight/environment.js";
|
|
12
|
+
import { prepareConfiguredOperatorReadiness } from "../../preflight/operator.js";
|
|
12
13
|
import { toErrorMessage } from "../../utils/errors.js";
|
|
13
14
|
import { normalizePathForDisplay, relativeToRoot } from "../../utils/path.js";
|
|
14
15
|
import { resolveWorkspacePath, VORATIQ_VERIFICATION_SESSIONS_DIR, } from "../../workspace/structure.js";
|
|
15
16
|
import { generateSessionId } from "../shared/session-id.js";
|
|
16
|
-
import {
|
|
17
|
+
import { resolveVerificationAgents } from "./agents.js";
|
|
18
|
+
import { VerifyPreflightError } from "./errors.js";
|
|
17
19
|
import { finalizeActiveVerification, registerActiveVerification, } from "./lifecycle.js";
|
|
18
20
|
import { resolveVerifyRubricMaxParallel } from "./max-parallel.js";
|
|
19
21
|
import { resolveVerifyTarget } from "./targets.js";
|
|
@@ -29,14 +31,22 @@ export async function executeVerifyCommand(input) {
|
|
|
29
31
|
target,
|
|
30
32
|
});
|
|
31
33
|
const verificationConfig = loadVerificationConfig({ root });
|
|
32
|
-
const
|
|
34
|
+
const verificationPlan = resolveVerificationAgents({
|
|
33
35
|
agentIds,
|
|
34
36
|
root,
|
|
35
37
|
agentOverrideFlag,
|
|
36
38
|
profileName,
|
|
37
39
|
});
|
|
38
|
-
await
|
|
39
|
-
|
|
40
|
+
const preflight = await prepareConfiguredOperatorReadiness({
|
|
41
|
+
root,
|
|
42
|
+
resolvedAgentIds: verificationPlan.agentIds,
|
|
43
|
+
includeEnvironment: false,
|
|
44
|
+
});
|
|
45
|
+
if (preflight.issues.length > 0) {
|
|
46
|
+
throw new VerifyPreflightError(preflight.issues, preflight.preProviderIssueCount);
|
|
47
|
+
}
|
|
48
|
+
const verificationAgents = preflight.agents;
|
|
49
|
+
const environment = loadOperatorEnvironment({ root });
|
|
40
50
|
const verificationId = generateSessionId();
|
|
41
51
|
const createdAt = new Date().toISOString();
|
|
42
52
|
const aliasMap = buildBlindedAliasMap(resolvedTarget);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { CliError } from "../../cli/errors.js";
|
|
2
|
+
import type { PreflightIssue } from "../../competition/shared/preflight.js";
|
|
3
|
+
export declare class VerifyError extends CliError {
|
|
4
|
+
constructor(headline: string, detailLines?: readonly string[], hintLines?: readonly string[]);
|
|
5
|
+
}
|
|
6
|
+
export declare class VerifyAgentNotFoundError extends VerifyError {
|
|
7
|
+
constructor(agentId: string);
|
|
8
|
+
}
|
|
9
|
+
export declare class VerifyPreflightError extends VerifyError {
|
|
10
|
+
readonly issues: readonly PreflightIssue[];
|
|
11
|
+
constructor(issues: readonly PreflightIssue[], preProviderIssueCount: number);
|
|
12
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { CliError } from "../../cli/errors.js";
|
|
2
|
+
import { formatOperatorPreflightIssueLines, resolveOperatorPreflightHintLines, } from "../../preflight/formatting.js";
|
|
3
|
+
export class VerifyError extends CliError {
|
|
4
|
+
constructor(headline, detailLines = [], hintLines = []) {
|
|
5
|
+
super(headline, detailLines, hintLines);
|
|
6
|
+
this.name = "VerifyError";
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export class VerifyAgentNotFoundError extends VerifyError {
|
|
10
|
+
constructor(agentId) {
|
|
11
|
+
super(`Verifier agent not found: ${agentId}`);
|
|
12
|
+
this.name = "VerifyAgentNotFoundError";
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export class VerifyPreflightError extends VerifyError {
|
|
16
|
+
issues;
|
|
17
|
+
constructor(issues, preProviderIssueCount) {
|
|
18
|
+
super("Preflight failed. Aborting verification.", formatOperatorPreflightIssueLines(issues), resolveOperatorPreflightHintLines(issues, preProviderIssueCount) ?? []);
|
|
19
|
+
this.issues = Array.from(issues);
|
|
20
|
+
this.name = "VerifyPreflightError";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { basename } from "node:path";
|
|
1
|
+
import { basename, join } from "node:path";
|
|
2
2
|
import { CliError, RunNotFoundCliError } from "../../cli/errors.js";
|
|
3
3
|
import { TERMINAL_MESSAGE_STATUSES } from "../../domain/message/model/types.js";
|
|
4
4
|
import { readMessageRecords } from "../../domain/message/persistence/adapter.js";
|
|
@@ -10,7 +10,10 @@ import { TERMINAL_SPEC_STATUSES } from "../../domain/spec/model/types.js";
|
|
|
10
10
|
import { readSpecRecords } from "../../domain/spec/persistence/adapter.js";
|
|
11
11
|
import { readVerificationRecords } from "../../domain/verify/persistence/adapter.js";
|
|
12
12
|
import { TERMINAL_RUN_STATUSES } from "../../status/index.js";
|
|
13
|
-
import {
|
|
13
|
+
import { pathExists } from "../../utils/fs.js";
|
|
14
|
+
import { normalizePathForDisplay, resolvePath } from "../../utils/path.js";
|
|
15
|
+
import { buildAgentWorkspacePaths } from "../../workspace/layout.js";
|
|
16
|
+
import { DIFF_FILENAME, MESSAGE_RESPONSE_FILENAME, } from "../../workspace/structure.js";
|
|
14
17
|
export async function resolveVerifyTarget(input) {
|
|
15
18
|
const { target } = input;
|
|
16
19
|
switch (target.kind) {
|
|
@@ -40,14 +43,31 @@ async function resolveSpecVerifyTarget(input) {
|
|
|
40
43
|
if (!TERMINAL_SPEC_STATUSES.includes(record.status)) {
|
|
41
44
|
throw new CliError(`Spec session \`${target.sessionId}\` is not complete.`, [`Status: \`${record.status}\`.`], ["Wait for the spec to finish before running `voratiq verify`."]);
|
|
42
45
|
}
|
|
46
|
+
const competitiveCandidates = record.agents
|
|
47
|
+
.filter((agent) => agent.status === "succeeded" && agent.outputPath)
|
|
48
|
+
.map((agent) => ({
|
|
49
|
+
canonicalId: agent.agentId,
|
|
50
|
+
forbiddenIdentityTokens: [agent.agentId],
|
|
51
|
+
}));
|
|
52
|
+
if (competitiveCandidates.length === 0) {
|
|
53
|
+
throw new CliError(`Spec session \`${target.sessionId}\` has no verifiable drafts.`, [], [
|
|
54
|
+
"Re-run `voratiq spec` to generate at least one succeeded draft before running `voratiq verify`.",
|
|
55
|
+
]);
|
|
56
|
+
}
|
|
57
|
+
const missingSpecArtifacts = await collectMissingSpecVerificationArtifacts({
|
|
58
|
+
root,
|
|
59
|
+
outputPaths: record.agents
|
|
60
|
+
.filter((agent) => agent.status === "succeeded" && typeof agent.outputPath === "string")
|
|
61
|
+
.map((agent) => agent.outputPath),
|
|
62
|
+
});
|
|
63
|
+
if (missingSpecArtifacts.length > 0) {
|
|
64
|
+
throw new CliError(`Spec session \`${target.sessionId}\` is missing required verification artifacts.`, missingSpecArtifacts.map((artifact) => `Missing: \`${artifact}\`.`), [
|
|
65
|
+
"Re-run `voratiq spec` to regenerate the retained artifacts before running `voratiq verify`.",
|
|
66
|
+
]);
|
|
67
|
+
}
|
|
43
68
|
return {
|
|
44
69
|
baseRevisionSha: resolveSpecBaseRevisionSha(record),
|
|
45
|
-
competitiveCandidates
|
|
46
|
-
.filter((agent) => agent.status === "succeeded" && agent.outputPath)
|
|
47
|
-
.map((agent) => ({
|
|
48
|
-
canonicalId: agent.agentId,
|
|
49
|
-
forbiddenIdentityTokens: [agent.agentId],
|
|
50
|
-
})),
|
|
70
|
+
competitiveCandidates,
|
|
51
71
|
target: {
|
|
52
72
|
kind: "spec",
|
|
53
73
|
sessionId: record.sessionId,
|
|
@@ -81,6 +101,16 @@ async function resolveRunVerifyTarget(input) {
|
|
|
81
101
|
if (candidateIds.length === 0) {
|
|
82
102
|
throw new CliError(`Run \`${target.sessionId}\` has no candidate agents to verify.`, [], ["Re-run `voratiq run` to generate verifiable candidates."]);
|
|
83
103
|
}
|
|
104
|
+
const missingRequiredArtifacts = await collectMissingRunVerificationArtifacts({
|
|
105
|
+
root,
|
|
106
|
+
record,
|
|
107
|
+
candidateIds,
|
|
108
|
+
});
|
|
109
|
+
if (missingRequiredArtifacts.length > 0) {
|
|
110
|
+
throw new CliError(`Run \`${target.sessionId}\` is missing required verification artifacts.`, missingRequiredArtifacts.map((artifact) => `Missing: \`${artifact}\`.`), [
|
|
111
|
+
"Re-run `voratiq run` to regenerate the retained artifacts before running `voratiq verify`.",
|
|
112
|
+
]);
|
|
113
|
+
}
|
|
84
114
|
return {
|
|
85
115
|
baseRevisionSha: record.baseRevisionSha,
|
|
86
116
|
competitiveCandidates: candidateIds.map((candidateId) => ({
|
|
@@ -117,16 +147,33 @@ async function resolveReductionVerifyTarget(input) {
|
|
|
117
147
|
if (!TERMINAL_REDUCTION_STATUSES.includes(record.status)) {
|
|
118
148
|
throw new CliError(`Reduction session \`${target.sessionId}\` is not complete.`, [`Status: \`${record.status}\`.`], ["Wait for the reduction to finish before running `voratiq verify`."]);
|
|
119
149
|
}
|
|
120
|
-
const referenceRepo = await resolveReductionReferenceRepo({
|
|
121
|
-
...input,
|
|
122
|
-
reductionRecord: record,
|
|
123
|
-
});
|
|
124
150
|
const competitiveCandidates = record.reducers
|
|
125
151
|
.filter((reducer) => reducer.status === "succeeded" && reducer.outputPath)
|
|
126
152
|
.map((reducer) => ({
|
|
127
153
|
canonicalId: reducer.agentId,
|
|
128
154
|
forbiddenIdentityTokens: [reducer.agentId],
|
|
129
155
|
}));
|
|
156
|
+
if (competitiveCandidates.length === 0) {
|
|
157
|
+
throw new CliError(`Reduction session \`${target.sessionId}\` has no verifiable reductions.`, [], [
|
|
158
|
+
"Re-run `voratiq reduce` to produce at least one succeeded reduction before running `voratiq verify`.",
|
|
159
|
+
]);
|
|
160
|
+
}
|
|
161
|
+
const missingReductionArtifacts = await collectMissingRetainedVerificationArtifacts({
|
|
162
|
+
root,
|
|
163
|
+
relativePaths: record.reducers
|
|
164
|
+
.filter((reducer) => reducer.status === "succeeded" &&
|
|
165
|
+
typeof reducer.outputPath === "string")
|
|
166
|
+
.map((reducer) => reducer.outputPath),
|
|
167
|
+
});
|
|
168
|
+
if (missingReductionArtifacts.length > 0) {
|
|
169
|
+
throw new CliError(`Reduction session \`${target.sessionId}\` is missing required verification artifacts.`, missingReductionArtifacts.map((artifact) => `Missing: \`${artifact}\`.`), [
|
|
170
|
+
"Re-run `voratiq reduce` to regenerate the retained artifacts before running `voratiq verify`.",
|
|
171
|
+
]);
|
|
172
|
+
}
|
|
173
|
+
const referenceRepo = await resolveReductionReferenceRepo({
|
|
174
|
+
...input,
|
|
175
|
+
reductionRecord: record,
|
|
176
|
+
});
|
|
130
177
|
if (referenceRepo.kind === "git") {
|
|
131
178
|
return {
|
|
132
179
|
baseRevisionSha: referenceRepo.baseRevisionSha,
|
|
@@ -177,6 +224,15 @@ async function resolveMessageVerifyTarget(input) {
|
|
|
177
224
|
"Re-run `voratiq message` to capture at least one succeeded response before running `voratiq verify`.",
|
|
178
225
|
]);
|
|
179
226
|
}
|
|
227
|
+
const missingMessageArtifacts = await collectMissingRetainedVerificationArtifacts({
|
|
228
|
+
root,
|
|
229
|
+
relativePaths: recipients.map((recipient) => recipient.outputPath),
|
|
230
|
+
});
|
|
231
|
+
if (missingMessageArtifacts.length > 0) {
|
|
232
|
+
throw new CliError(`Message session \`${target.sessionId}\` is missing required verification artifacts.`, missingMessageArtifacts.map((artifact) => `Missing: \`${artifact}\`.`), [
|
|
233
|
+
"Re-run `voratiq message` to regenerate the retained artifacts before running `voratiq verify`.",
|
|
234
|
+
]);
|
|
235
|
+
}
|
|
180
236
|
return {
|
|
181
237
|
competitiveCandidates: recipients.map((recipient) => ({
|
|
182
238
|
canonicalId: recipient.agentId,
|
|
@@ -189,6 +245,46 @@ async function resolveMessageVerifyTarget(input) {
|
|
|
189
245
|
messageRecord: record,
|
|
190
246
|
};
|
|
191
247
|
}
|
|
248
|
+
async function collectMissingSpecVerificationArtifacts(options) {
|
|
249
|
+
return collectMissingRetainedVerificationArtifacts({
|
|
250
|
+
root: options.root,
|
|
251
|
+
relativePaths: options.outputPaths,
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
async function collectMissingRunVerificationArtifacts(options) {
|
|
255
|
+
const { root, record, candidateIds } = options;
|
|
256
|
+
const missing = new Set();
|
|
257
|
+
const specAbsolute = resolvePath(root, record.spec.path);
|
|
258
|
+
if (!(await pathExists(specAbsolute))) {
|
|
259
|
+
missing.add(normalizePathForDisplay(record.spec.path));
|
|
260
|
+
}
|
|
261
|
+
for (const candidateId of candidateIds) {
|
|
262
|
+
const runAgentRecord = record.agents.find((agent) => agent.agentId === candidateId);
|
|
263
|
+
if (runAgentRecord?.artifacts?.diffCaptured !== true) {
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
const paths = buildAgentWorkspacePaths({
|
|
267
|
+
root,
|
|
268
|
+
runId: record.runId,
|
|
269
|
+
agentId: candidateId,
|
|
270
|
+
});
|
|
271
|
+
const diffAbsolute = join(paths.artifactsPath, DIFF_FILENAME);
|
|
272
|
+
if (!(await pathExists(diffAbsolute))) {
|
|
273
|
+
missing.add(normalizePathForDisplay(join(".voratiq", "run", "sessions", record.runId, candidateId, "artifacts", DIFF_FILENAME)));
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
return Array.from(missing).sort((left, right) => left.localeCompare(right));
|
|
277
|
+
}
|
|
278
|
+
async function collectMissingRetainedVerificationArtifacts(options) {
|
|
279
|
+
const { root, relativePaths } = options;
|
|
280
|
+
const missing = new Set();
|
|
281
|
+
for (const relativePath of relativePaths) {
|
|
282
|
+
if (!(await pathExists(resolvePath(root, relativePath)))) {
|
|
283
|
+
missing.add(normalizePathForDisplay(relativePath));
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return Array.from(missing).sort((left, right) => left.localeCompare(right));
|
|
287
|
+
}
|
|
192
288
|
function collectRunCandidateIdentityTokens(options) {
|
|
193
289
|
const { runRecord, candidateId } = options;
|
|
194
290
|
const tokens = new Set();
|
|
@@ -7,5 +7,5 @@ export interface FormatPreflightIssueLinesOptions {
|
|
|
7
7
|
readonly unlabeledAgentIds?: readonly string[];
|
|
8
8
|
}
|
|
9
9
|
export declare const PREFLIGHT_SUMMARY_MAX_CHARS: 120;
|
|
10
|
-
export declare const PREFLIGHT_HINT: "Run `voratiq
|
|
10
|
+
export declare const PREFLIGHT_HINT: "Run `voratiq doctor --fix` to repair workspace setup.";
|
|
11
11
|
export declare function formatPreflightIssueLines(issues: readonly PreflightIssue[], options?: FormatPreflightIssueLinesOptions): string[];
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export const PREFLIGHT_SUMMARY_MAX_CHARS = 120;
|
|
2
|
-
export const PREFLIGHT_HINT = "Run `voratiq
|
|
2
|
+
export const PREFLIGHT_HINT = "Run `voratiq doctor --fix` to repair workspace setup.";
|
|
3
|
+
const SETTINGS_FILE_MESSAGE_PATTERN = /^Invalid settings file at (?:(?:.+\/)?(?:\.voratiq\/)?)settings\.yaml(?::\s*(.+))?$/u;
|
|
3
4
|
export function formatPreflightIssueLines(issues, options = {}) {
|
|
4
5
|
const { maxChars = PREFLIGHT_SUMMARY_MAX_CHARS, unlabeledAgentIds = [] } = options;
|
|
5
6
|
const unlabeled = new Set(unlabeledAgentIds);
|
|
@@ -17,15 +18,27 @@ function formatIssueLine(agentId, message, unlabeledAgentIds) {
|
|
|
17
18
|
if (unlabeledAgentIds.has(agentId)) {
|
|
18
19
|
return `- ${message}`;
|
|
19
20
|
}
|
|
20
|
-
return `-
|
|
21
|
+
return `- \`${agentId}\`: ${message}`;
|
|
21
22
|
}
|
|
22
23
|
function normalizeIssueMessage(message) {
|
|
23
24
|
const split = message
|
|
24
25
|
.split(/\r?\n/u)
|
|
25
26
|
.map((line) => line.replace(/\s+/gu, " ").trim())
|
|
27
|
+
.map(normalizeIssueText)
|
|
26
28
|
.filter((line) => line.length > 0);
|
|
27
29
|
return split.length > 0 ? split : ["unknown error"];
|
|
28
30
|
}
|
|
31
|
+
function normalizeIssueText(line) {
|
|
32
|
+
const settingsMatch = SETTINGS_FILE_MESSAGE_PATTERN.exec(line);
|
|
33
|
+
if (!settingsMatch) {
|
|
34
|
+
return line;
|
|
35
|
+
}
|
|
36
|
+
const detail = settingsMatch[1]?.trim();
|
|
37
|
+
if (!detail) {
|
|
38
|
+
return "Invalid `settings.yaml`.";
|
|
39
|
+
}
|
|
40
|
+
return `Invalid \`settings.yaml\`: ${detail}`;
|
|
41
|
+
}
|
|
29
42
|
function truncateLine(value, maxChars) {
|
|
30
43
|
if (value.length <= maxChars) {
|
|
31
44
|
return value;
|