agent-valley 2.2.1 → 2.3.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/dist/assets/plugin.json +1 -1
- package/dist/index.js +470 -119
- package/dist/supervisor.js +75 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6439,6 +6439,72 @@ var init_zod = __esm(() => {
|
|
|
6439
6439
|
init_external();
|
|
6440
6440
|
});
|
|
6441
6441
|
|
|
6442
|
+
// ../../packages/core/src/oma/skill-matrix-schema.ts
|
|
6443
|
+
var hash, name, bounded, path, skillCompatibilityConfigSchema, skillCompatibilityPolicySchema, omaConfigSchema, matrixSkillSchema, matrixReportSchema;
|
|
6444
|
+
var init_skill_matrix_schema = __esm(() => {
|
|
6445
|
+
init_zod();
|
|
6446
|
+
hash = string2().regex(/^[a-f0-9]{64}$/);
|
|
6447
|
+
name = string2().regex(/^[a-z0-9][a-z0-9-]{0,127}$/);
|
|
6448
|
+
bounded = string2().trim().min(1).max(2000);
|
|
6449
|
+
path = string2().min(1).max(4096).refine((value) => !value.includes("\x00"));
|
|
6450
|
+
skillCompatibilityConfigSchema = strictObject({
|
|
6451
|
+
report_path: path,
|
|
6452
|
+
max_age_hours: number2().finite().positive().max(8760).default(168),
|
|
6453
|
+
mode: _enum(["warn", "require"])
|
|
6454
|
+
});
|
|
6455
|
+
skillCompatibilityPolicySchema = strictObject({
|
|
6456
|
+
reportPath: path,
|
|
6457
|
+
maxAgeHours: number2().finite().positive().max(8760),
|
|
6458
|
+
mode: _enum(["warn", "require"])
|
|
6459
|
+
});
|
|
6460
|
+
omaConfigSchema = strictObject({
|
|
6461
|
+
mode: _enum(["off", "strict"]).default("off"),
|
|
6462
|
+
skill_compatibility: skillCompatibilityConfigSchema.optional()
|
|
6463
|
+
});
|
|
6464
|
+
matrixSkillSchema = object({
|
|
6465
|
+
name,
|
|
6466
|
+
hash,
|
|
6467
|
+
caseId: bounded,
|
|
6468
|
+
requiredFiles: array(path).min(1).max(500),
|
|
6469
|
+
missingFiles: array(path).max(500),
|
|
6470
|
+
excludedReferences: array(object({ path, reason: bounded })).max(500)
|
|
6471
|
+
});
|
|
6472
|
+
matrixReportSchema = object({
|
|
6473
|
+
schemaVersion: literal(1),
|
|
6474
|
+
kind: literal("skill-compatibility-matrix"),
|
|
6475
|
+
mode: _enum(["plan", "live"]),
|
|
6476
|
+
status: _enum(["planned", "completed", "cancelled", "interrupted"]),
|
|
6477
|
+
createdAt: exports_iso.datetime(),
|
|
6478
|
+
omaVersion: bounded,
|
|
6479
|
+
host: object({ platform: bounded, arch: bounded, node: bounded }),
|
|
6480
|
+
suiteHash: hash,
|
|
6481
|
+
sourceKind: _enum(["synthetic", "installed"]),
|
|
6482
|
+
delivery: _enum(["native", "injected"]),
|
|
6483
|
+
auditScope: _enum(["fixture-contract", "read-reference"]),
|
|
6484
|
+
protocolVersion: literal("oma-skill-matrix-v2"),
|
|
6485
|
+
bundle: object({ hash, skills: array(matrixSkillSchema).min(1).max(100) }).optional(),
|
|
6486
|
+
cases: array(object({ id: bounded, skill: name })).max(100),
|
|
6487
|
+
models: object({ claude: bounded.nullable(), codex: bounded.nullable() }),
|
|
6488
|
+
cells: array(object({
|
|
6489
|
+
caseId: bounded,
|
|
6490
|
+
skill: name,
|
|
6491
|
+
vendor: _enum(["claude", "codex"]),
|
|
6492
|
+
status: _enum(["pass", "fail", "unverifiable", "error"]),
|
|
6493
|
+
contentHash: hash,
|
|
6494
|
+
checks: array(object({
|
|
6495
|
+
id: bounded,
|
|
6496
|
+
status: _enum(["pass", "fail", "unverifiable"]),
|
|
6497
|
+
detail: bounded,
|
|
6498
|
+
proof: _enum(["read", "canary"]).optional()
|
|
6499
|
+
})).max(1000),
|
|
6500
|
+
nativeActivation: _enum(["observed", "unobserved"]),
|
|
6501
|
+
cliVersion: string2().regex(/^[\w .()+/-]{1,160}$/).nullable(),
|
|
6502
|
+
model: bounded.nullable(),
|
|
6503
|
+
durationMs: number2().finite().nonnegative()
|
|
6504
|
+
})).max(200)
|
|
6505
|
+
});
|
|
6506
|
+
});
|
|
6507
|
+
|
|
6442
6508
|
// ../../packages/core/src/config/task-schema.ts
|
|
6443
6509
|
var reportPath, taskSchema, resolvedTaskSchema;
|
|
6444
6510
|
var init_task_schema = __esm(() => {
|
|
@@ -6896,6 +6962,7 @@ var init_execution = __esm(() => {
|
|
|
6896
6962
|
var actorType, text, amount, routingCandidateSchema, chiefOperatingPolicySchema, operatingRunSchema, routeEvidenceSchema, reviewDecisionSchema, chiefOperationsSchema;
|
|
6897
6963
|
var init_operations = __esm(() => {
|
|
6898
6964
|
init_zod();
|
|
6965
|
+
init_skill_matrix_schema();
|
|
6899
6966
|
actorType = string2().regex(/^[a-z0-9][a-z0-9-]{0,127}$/);
|
|
6900
6967
|
text = string2().trim().min(1).max(2000);
|
|
6901
6968
|
amount = number2().finite().nonnegative();
|
|
@@ -6914,6 +6981,7 @@ var init_operations = __esm(() => {
|
|
|
6914
6981
|
reviewVendor: _enum(["prefer", "require", "off"]),
|
|
6915
6982
|
readyActors: array(actorType).max(20).optional(),
|
|
6916
6983
|
memory: boolean2(),
|
|
6984
|
+
skillCompatibility: skillCompatibilityPolicySchema.optional(),
|
|
6917
6985
|
metricTargets: array(strictObject({
|
|
6918
6986
|
name: text,
|
|
6919
6987
|
unit: text.optional(),
|
|
@@ -7232,7 +7300,7 @@ function chiefExecutionPolicy(config) {
|
|
|
7232
7300
|
autoResume: execution.auto_resume
|
|
7233
7301
|
} : {});
|
|
7234
7302
|
}
|
|
7235
|
-
function chiefOperatingPolicy(config, readyActors, automatic = true) {
|
|
7303
|
+
function chiefOperatingPolicy(config, readyActors, automatic = true, skillCompatibility) {
|
|
7236
7304
|
return chiefOperatingPolicySchema.parse({
|
|
7237
7305
|
routing: config.routing ? {
|
|
7238
7306
|
candidates: config.routing.candidates.map((item) => ({
|
|
@@ -7247,7 +7315,8 @@ function chiefOperatingPolicy(config, readyActors, automatic = true) {
|
|
|
7247
7315
|
reviewVendor: config.review_vendor ?? "prefer",
|
|
7248
7316
|
memory: config.memory ?? true,
|
|
7249
7317
|
metricTargets: config.metric_targets,
|
|
7250
|
-
readyActors
|
|
7318
|
+
readyActors,
|
|
7319
|
+
skillCompatibility
|
|
7251
7320
|
});
|
|
7252
7321
|
}
|
|
7253
7322
|
function chiefCapturePolicy(config) {
|
|
@@ -14575,7 +14644,7 @@ function mergeConfigs(global2, project, env) {
|
|
|
14575
14644
|
tunnel: buildTunnelConfig(project),
|
|
14576
14645
|
verify: buildVerifyConfig(project),
|
|
14577
14646
|
task: project?.task?.kind === "analysis" ? { kind: "analysis", reportPath: project.task.report_path } : { kind: "code" },
|
|
14578
|
-
oma:
|
|
14647
|
+
oma: project?.oma ?? { mode: "off" },
|
|
14579
14648
|
chief: global2?.chief || project?.chief ? mergeChiefConfig(global2?.chief, project?.chief) : undefined
|
|
14580
14649
|
};
|
|
14581
14650
|
}
|
|
@@ -14613,6 +14682,7 @@ Symphony cannot start until all config errors are resolved.`);
|
|
|
14613
14682
|
var globalConfigSchema, projectConfigSchema, githubConfigSchema, mergedConfigSchema;
|
|
14614
14683
|
var init_yaml_loader = __esm(() => {
|
|
14615
14684
|
init_zod();
|
|
14685
|
+
init_skill_matrix_schema();
|
|
14616
14686
|
init_actor_schema();
|
|
14617
14687
|
init_budget_schema();
|
|
14618
14688
|
init_chief_schema();
|
|
@@ -14706,7 +14776,7 @@ var init_yaml_loader = __esm(() => {
|
|
|
14706
14776
|
tunnel: tunnelProjectSchema,
|
|
14707
14777
|
verify: verifyProjectSchema,
|
|
14708
14778
|
task: taskSchema.optional(),
|
|
14709
|
-
oma:
|
|
14779
|
+
oma: omaConfigSchema.optional(),
|
|
14710
14780
|
chief: chiefConfigSchema.optional()
|
|
14711
14781
|
}).strict().overwrite(normalizeActorDefaults);
|
|
14712
14782
|
githubConfigSchema = object({
|
|
@@ -14775,7 +14845,7 @@ var init_yaml_loader = __esm(() => {
|
|
|
14775
14845
|
tunnel: tunnelMergedSchema,
|
|
14776
14846
|
verify: verifyMergedSchema,
|
|
14777
14847
|
task: resolvedTaskSchema.optional(),
|
|
14778
|
-
oma:
|
|
14848
|
+
oma: omaConfigSchema.optional(),
|
|
14779
14849
|
chief: chiefConfigSchema.optional()
|
|
14780
14850
|
}).superRefine((cfg, ctx) => {
|
|
14781
14851
|
if (cfg.trackerKind === "linear") {
|
|
@@ -20724,7 +20794,7 @@ var init_readdirp = __esm(() => {
|
|
|
20724
20794
|
|
|
20725
20795
|
// ../../node_modules/.bun/chokidar@5.0.0/node_modules/chokidar/handler.js
|
|
20726
20796
|
import { watch as fs_watch, unwatchFile, watchFile } from "node:fs";
|
|
20727
|
-
import { realpath as fsrealpath, lstat as lstat18, open as
|
|
20797
|
+
import { realpath as fsrealpath, lstat as lstat18, open as open12, stat as stat4 } from "node:fs/promises";
|
|
20728
20798
|
import { type as osType } from "node:os";
|
|
20729
20799
|
import * as sp from "node:path";
|
|
20730
20800
|
function createFsWatchInstance(path, options, listener, errHandler, emitRaw) {
|
|
@@ -21066,7 +21136,7 @@ var STR_DATA = "data", STR_END = "end", STR_CLOSE = "close", EMPTY_FN = () => {}
|
|
|
21066
21136
|
cont.watcherUnusable = true;
|
|
21067
21137
|
if (isWindows && error.code === "EPERM") {
|
|
21068
21138
|
try {
|
|
21069
|
-
const fd = await
|
|
21139
|
+
const fd = await open12(path, "r");
|
|
21070
21140
|
await fd.close();
|
|
21071
21141
|
broadcastErr(error);
|
|
21072
21142
|
} catch (err) {}
|
|
@@ -22699,7 +22769,7 @@ var init_agent_provisioning = __esm(() => {
|
|
|
22699
22769
|
import { mkdtempSync as mkdtempSync2, rmSync as rmSync3 } from "node:fs";
|
|
22700
22770
|
import { chmod as chmod4, lstat as lstat19, readdir as readdir12, readFile as readFile16, realpath as realpath25, unlink as unlink8, writeFile as writeFile14 } from "node:fs/promises";
|
|
22701
22771
|
import { homedir as homedir8, tmpdir as tmpdir5 } from "node:os";
|
|
22702
|
-
import { delimiter as delimiter4, isAbsolute as isAbsolute15, join as join47, relative as relative14, resolve as
|
|
22772
|
+
import { delimiter as delimiter4, isAbsolute as isAbsolute15, join as join47, relative as relative14, resolve as resolve28 } from "node:path";
|
|
22703
22773
|
function defaults2() {
|
|
22704
22774
|
const home = homedir8();
|
|
22705
22775
|
return {
|
|
@@ -22773,7 +22843,7 @@ async function restoreConfig(agents, snapshots) {
|
|
|
22773
22843
|
async function workspacePath(input) {
|
|
22774
22844
|
if (!input.trim() || !isAbsolute15(input))
|
|
22775
22845
|
return null;
|
|
22776
|
-
const root =
|
|
22846
|
+
const root = resolve28(input);
|
|
22777
22847
|
if (!await directory2(root))
|
|
22778
22848
|
return null;
|
|
22779
22849
|
for (const path of [join47(root, ".agents"), join47(root, ".agents", "skills")]) {
|
|
@@ -24399,7 +24469,7 @@ var init_workspace_step = __esm(() => {
|
|
|
24399
24469
|
|
|
24400
24470
|
// src/setup/noninteractive-config.ts
|
|
24401
24471
|
import { lstat as lstat20, realpath as realpath26 } from "node:fs/promises";
|
|
24402
|
-
import { isAbsolute as isAbsolute17, join as join48, parse as parsePath, resolve as
|
|
24472
|
+
import { isAbsolute as isAbsolute17, join as join48, parse as parsePath, resolve as resolve29 } from "node:path";
|
|
24403
24473
|
function validateNoninteractiveOptions(options) {
|
|
24404
24474
|
if (!options.yes || options.edit || options.mode !== undefined && options.mode !== "order")
|
|
24405
24475
|
throw new Error("Use av setup --yes only for local order setup; --edit and --mode tracker require interactive setup.");
|
|
@@ -24480,13 +24550,13 @@ async function prepareNoninteractiveConfig(options, deps) {
|
|
|
24480
24550
|
validateNoninteractiveOptions(options);
|
|
24481
24551
|
let projectRoot;
|
|
24482
24552
|
try {
|
|
24483
|
-
projectRoot = await realpath26(
|
|
24553
|
+
projectRoot = await realpath26(resolve29(deps.projectRoot));
|
|
24484
24554
|
if (!(await lstat20(projectRoot)).isDirectory())
|
|
24485
24555
|
throw new Error("not a directory");
|
|
24486
24556
|
} catch {
|
|
24487
24557
|
throw new Error(`AV configuration directory ${deps.projectRoot} does not exist. Run av setup from an existing directory.`);
|
|
24488
24558
|
}
|
|
24489
|
-
const globalPath =
|
|
24559
|
+
const globalPath = resolve29(deps.globalConfigPath);
|
|
24490
24560
|
const projectPath = join48(projectRoot, "av.yaml");
|
|
24491
24561
|
const project = await configFile(projectPath, projectConfigSchema);
|
|
24492
24562
|
const global2 = await configFile(globalPath, globalConfigSchema);
|
|
@@ -24504,7 +24574,7 @@ async function prepareNoninteractiveConfig(options, deps) {
|
|
|
24504
24574
|
}
|
|
24505
24575
|
const savedWorkspace = project.raw.workspace?.root;
|
|
24506
24576
|
const selectedWorkspace = options.workspace ?? savedWorkspace ?? projectRoot;
|
|
24507
|
-
const workspacePath = isAbsolute17(selectedWorkspace) ? selectedWorkspace :
|
|
24577
|
+
const workspacePath = isAbsolute17(selectedWorkspace) ? selectedWorkspace : resolve29(projectRoot, selectedWorkspace);
|
|
24508
24578
|
const workspaceError = await validateOrderWorkspace(workspacePath);
|
|
24509
24579
|
if (workspaceError)
|
|
24510
24580
|
throw new Error(workspaceError);
|
|
@@ -24539,7 +24609,7 @@ var init_noninteractive_config = __esm(() => {
|
|
|
24539
24609
|
});
|
|
24540
24610
|
|
|
24541
24611
|
// src/setup/noninteractive.ts
|
|
24542
|
-
import { join as join49, parse as parsePath2, resolve as
|
|
24612
|
+
import { join as join49, parse as parsePath2, resolve as resolve30 } from "node:path";
|
|
24543
24613
|
function rerunCommand(result, options) {
|
|
24544
24614
|
const quote = (value) => `'${value.replace(/'/g, "'\\''")}'`;
|
|
24545
24615
|
return `cd ${quote(result.projectRoot)} && av setup --yes --actor ${result.chief.actorType} --model ${quote(result.chief.model ?? "")} --workspace ${quote(result.workspace ?? result.projectRoot)} --oma ${options.oma ?? "prepare"} --json`;
|
|
@@ -24550,11 +24620,11 @@ async function setupNoninteractive(options, overrides = {}) {
|
|
|
24550
24620
|
version: 1,
|
|
24551
24621
|
status: "failed",
|
|
24552
24622
|
exitCode: 1,
|
|
24553
|
-
projectRoot:
|
|
24623
|
+
projectRoot: resolve30(deps.projectRoot),
|
|
24554
24624
|
workspace: null,
|
|
24555
24625
|
config: {
|
|
24556
|
-
project: join49(
|
|
24557
|
-
global:
|
|
24626
|
+
project: join49(resolve30(deps.projectRoot), "av.yaml"),
|
|
24627
|
+
global: resolve30(deps.globalConfigPath),
|
|
24558
24628
|
saved: false
|
|
24559
24629
|
},
|
|
24560
24630
|
chief: {
|
|
@@ -25127,18 +25197,18 @@ async function stepMetrics(ctx) {
|
|
|
25127
25197
|
draft.file = file;
|
|
25128
25198
|
}
|
|
25129
25199
|
for (const field of ["value_path", "timestamp_path", "unit_path"]) {
|
|
25130
|
-
const value = await text12(`JSON ${field}`, old?.[field] ?? field.replace("_path", ""),
|
|
25200
|
+
const value = await text12(`JSON ${field}`, old?.[field] ?? field.replace("_path", ""), path4);
|
|
25131
25201
|
if (navigated2(value))
|
|
25132
25202
|
return value;
|
|
25133
25203
|
draft[field] = value;
|
|
25134
25204
|
}
|
|
25135
|
-
const start = await text12("JSON measurement window start path (optional; blank omits window)", old?.window_start_path ?? "", (value) => value ?
|
|
25205
|
+
const start = await text12("JSON measurement window start path (optional; blank omits window)", old?.window_start_path ?? "", (value) => value ? path4(value) : undefined);
|
|
25136
25206
|
if (navigated2(start))
|
|
25137
25207
|
return start;
|
|
25138
25208
|
delete draft.window_start_path;
|
|
25139
25209
|
delete draft.window_end_path;
|
|
25140
25210
|
if (start) {
|
|
25141
|
-
const end = await text12("JSON measurement window end path", old?.window_end_path ?? "window.end",
|
|
25211
|
+
const end = await text12("JSON measurement window end path", old?.window_end_path ?? "window.end", path4);
|
|
25142
25212
|
if (navigated2(end))
|
|
25143
25213
|
return end;
|
|
25144
25214
|
draft.window_start_path = start;
|
|
@@ -25184,7 +25254,7 @@ async function stepMetrics(ctx) {
|
|
|
25184
25254
|
ctx.chiefChanged = true;
|
|
25185
25255
|
log2.info("Metric settings are saved after confirmation. Measurements are collected at mission runtime; setup does not contact the source. Set --duration or chief.execution.max_duration_sec long enough for work and the full measurement/observation windows. The default mission limit is 86400 seconds including waits; Stripe's default measurement window is also 86400 seconds.");
|
|
25186
25256
|
}
|
|
25187
|
-
var envName3 = (value) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(value), navigated2 = (value) => typeof value !== "string", required2 = (limit) => (value) => value && value.length <= limit ? undefined : `Enter 1 to ${limit} characters.`, environment = (optional = false) => (value) => optional && !value || envName3(value) ? undefined : "Enter an environment variable name, never a token or URL.", number4 = (minimum, maximum) => (value) => value && Number.isInteger(Number(value)) && Number(value) >= minimum && Number(value) <= maximum ? undefined : `Enter a whole number from ${minimum} to ${maximum}.`,
|
|
25257
|
+
var envName3 = (value) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(value), navigated2 = (value) => typeof value !== "string", required2 = (limit) => (value) => value && value.length <= limit ? undefined : `Enter 1 to ${limit} characters.`, environment = (optional = false) => (value) => optional && !value || envName3(value) ? undefined : "Enter an environment variable name, never a token or URL.", number4 = (minimum, maximum) => (value) => value && Number.isInteger(Number(value)) && Number(value) >= minimum && Number(value) <= maximum ? undefined : `Enter a whole number from ${minimum} to ${maximum}.`, path4 = (value) => {
|
|
25188
25258
|
const result = metricSourceSchema.shape.value_path.safeParse(value);
|
|
25189
25259
|
return result.success ? undefined : "Use dot-separated JSON keys or array indexes, without prototype keys.";
|
|
25190
25260
|
};
|
|
@@ -27762,7 +27832,7 @@ init_project_config_path();
|
|
|
27762
27832
|
init_yaml_loader();
|
|
27763
27833
|
import { spawn as spawn24, spawnSync as spawnSync5 } from "node:child_process";
|
|
27764
27834
|
import { existsSync as existsSync10, unlinkSync as unlinkSync2 } from "node:fs";
|
|
27765
|
-
import { resolve as
|
|
27835
|
+
import { resolve as resolve31 } from "node:path";
|
|
27766
27836
|
|
|
27767
27837
|
// ../../packages/core/src/version.ts
|
|
27768
27838
|
import { readFileSync as readFileSync2 } from "node:fs";
|
|
@@ -27872,7 +27942,7 @@ function humanReadableArgName(arg) {
|
|
|
27872
27942
|
// ../../node_modules/.bun/commander@15.0.0/node_modules/commander/lib/command.js
|
|
27873
27943
|
import { EventEmitter } from "node:events";
|
|
27874
27944
|
import childProcess from "node:child_process";
|
|
27875
|
-
import
|
|
27945
|
+
import path2 from "node:path";
|
|
27876
27946
|
import fs from "node:fs";
|
|
27877
27947
|
import process2 from "node:process";
|
|
27878
27948
|
import { stripVTControlCharacters as stripVTControlCharacters2 } from "node:util";
|
|
@@ -29016,10 +29086,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
29016
29086
|
args = args.slice();
|
|
29017
29087
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
29018
29088
|
function findFile(baseDir, baseName) {
|
|
29019
|
-
const localBin =
|
|
29089
|
+
const localBin = path2.resolve(baseDir, baseName);
|
|
29020
29090
|
if (fs.existsSync(localBin))
|
|
29021
29091
|
return localBin;
|
|
29022
|
-
if (sourceExt.includes(
|
|
29092
|
+
if (sourceExt.includes(path2.extname(baseName)))
|
|
29023
29093
|
return;
|
|
29024
29094
|
const foundExt = sourceExt.find((ext) => fs.existsSync(`${localBin}${ext}`));
|
|
29025
29095
|
if (foundExt)
|
|
@@ -29037,19 +29107,19 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
29037
29107
|
} catch {
|
|
29038
29108
|
resolvedScriptPath = this._scriptPath;
|
|
29039
29109
|
}
|
|
29040
|
-
executableDir =
|
|
29110
|
+
executableDir = path2.resolve(path2.dirname(resolvedScriptPath), executableDir);
|
|
29041
29111
|
}
|
|
29042
29112
|
if (executableDir) {
|
|
29043
29113
|
let localFile = findFile(executableDir, executableFile);
|
|
29044
29114
|
if (!localFile && !subcommand._executableFile && this._scriptPath) {
|
|
29045
|
-
const legacyName =
|
|
29115
|
+
const legacyName = path2.basename(this._scriptPath, path2.extname(this._scriptPath));
|
|
29046
29116
|
if (legacyName !== this._name) {
|
|
29047
29117
|
localFile = findFile(executableDir, `${legacyName}-${subcommand._name}`);
|
|
29048
29118
|
}
|
|
29049
29119
|
}
|
|
29050
29120
|
executableFile = localFile || executableFile;
|
|
29051
29121
|
}
|
|
29052
|
-
const launchWithNode = sourceExt.includes(
|
|
29122
|
+
const launchWithNode = sourceExt.includes(path2.extname(executableFile));
|
|
29053
29123
|
let proc;
|
|
29054
29124
|
if (process2.platform !== "win32") {
|
|
29055
29125
|
if (launchWithNode) {
|
|
@@ -29640,13 +29710,13 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
29640
29710
|
cmd.helpGroup(this._defaultCommandGroup);
|
|
29641
29711
|
}
|
|
29642
29712
|
nameFromFilename(filename) {
|
|
29643
|
-
this._name =
|
|
29713
|
+
this._name = path2.basename(filename, path2.extname(filename));
|
|
29644
29714
|
return this;
|
|
29645
29715
|
}
|
|
29646
|
-
executableDir(
|
|
29647
|
-
if (
|
|
29716
|
+
executableDir(path) {
|
|
29717
|
+
if (path === undefined)
|
|
29648
29718
|
return this._executableDir;
|
|
29649
|
-
this._executableDir =
|
|
29719
|
+
this._executableDir = path;
|
|
29650
29720
|
return this;
|
|
29651
29721
|
}
|
|
29652
29722
|
helpInformation(contextOptions) {
|
|
@@ -48938,7 +49008,7 @@ var sha256 = string2().regex(/^[a-f0-9]{64}$/);
|
|
|
48938
49008
|
function safeVerificationPath(path) {
|
|
48939
49009
|
return path.length > 0 && path.length <= 1024 && !isAbsolute2(path) && !/^[a-z]:/i.test(path) && !/[\\\0\r\n]/.test(path) && path.split("/").every((part) => part !== "" && part !== "." && part !== "..") && !/^(?:\.git(?:\/|$)|\.agent-valley(?:\/|$)|\.agents\/(?:state|results)(?:\/|$))/.test(path);
|
|
48940
49010
|
}
|
|
48941
|
-
var
|
|
49011
|
+
var path3 = string2().refine(safeVerificationPath, "Use a literal relative product path inside the worktree.");
|
|
48942
49012
|
var testPath = (name, nodeOnly = false) => safeVerificationPath(name) && !name.startsWith("-") && !/[*?{}]/.test(name) && !name.startsWith("node_modules/") && (nodeOnly ? /(?:\.test|\.spec)\.(?:js|mjs|cjs)$/ : /(?:\.test|\.spec)\.(?:[cm]?[jt]sx?)$/).test(name);
|
|
48943
49013
|
function verificationCommandTestPaths(program, args) {
|
|
48944
49014
|
if (program === "bun" && args[0] === "test")
|
|
@@ -48975,14 +49045,14 @@ function safeVerificationCommand(program, args) {
|
|
|
48975
49045
|
var goalVerificationCheckSchema = discriminatedUnion("kind", [
|
|
48976
49046
|
strictObject({
|
|
48977
49047
|
kind: literal("file"),
|
|
48978
|
-
path:
|
|
49048
|
+
path: path3,
|
|
48979
49049
|
minBytes: number2().int().min(1).max(4194304).default(1),
|
|
48980
49050
|
contains: array(text4).min(1).max(10).optional(),
|
|
48981
49051
|
sha256: sha256.optional()
|
|
48982
49052
|
}),
|
|
48983
49053
|
strictObject({
|
|
48984
49054
|
kind: literal("json"),
|
|
48985
|
-
path:
|
|
49055
|
+
path: path3,
|
|
48986
49056
|
pointer: string2().max(1024).refine((value) => value === "" || /^(?:\/(?:[^~]|~[01])*)+$/.test(value), {
|
|
48987
49057
|
message: "Use an RFC 6901 JSON pointer such as /engines/node."
|
|
48988
49058
|
}),
|
|
@@ -49444,16 +49514,29 @@ function routeEvidence(mission) {
|
|
|
49444
49514
|
function price2(candidate) {
|
|
49445
49515
|
return candidate.inputPerMillionUsd !== undefined && candidate.outputPerMillionUsd !== undefined ? candidate.inputPerMillionUsd + candidate.outputPerMillionUsd : Number.POSITIVE_INFINITY;
|
|
49446
49516
|
}
|
|
49447
|
-
function
|
|
49517
|
+
function workActorCandidates(mission, actor, preserveExplicit = false) {
|
|
49448
49518
|
const routing = mission.operatingPolicy?.routing;
|
|
49449
|
-
if (!routing || actor.id === mission.chiefId || !mission.availableAgents && actor.model)
|
|
49519
|
+
if (!routing || actor.id === mission.chiefId || !mission.availableAgents && (actor.model || preserveExplicit))
|
|
49520
|
+
return [{ actorType: actor.agentType, model: actor.model }];
|
|
49521
|
+
const ready = mission.operatingPolicy?.readyActors ?? mission.availableAgents ?? [];
|
|
49522
|
+
return routing.candidates.filter((candidate) => ready.includes(candidate.actorType));
|
|
49523
|
+
}
|
|
49524
|
+
function selectWorkActor(mission, actor, taskId, compatibleRoutes) {
|
|
49525
|
+
const routing = mission.operatingPolicy?.routing;
|
|
49526
|
+
if (!routing || actor.id === mission.chiefId || !mission.availableAgents && (actor.model || compatibleRoutes)) {
|
|
49527
|
+
if (compatibleRoutes && !compatibleRoutes.has(routeKey({ actorType: actor.agentType, model: actor.model })))
|
|
49528
|
+
throw new Error("Skill compatibility required: the configured Actor/model has no current passing evidence. Refresh oma.skill_compatibility.report_path in av.yaml; explicit Actors are not rerouted.");
|
|
49450
49529
|
return { actor, reason: "Preserved the configured Actor and explicit model." };
|
|
49530
|
+
}
|
|
49451
49531
|
const ready = mission.operatingPolicy?.readyActors ?? mission.availableAgents ?? [];
|
|
49452
49532
|
const candidates = routing.candidates.filter((candidate) => ready.includes(candidate.actorType));
|
|
49453
49533
|
if (!candidates.length)
|
|
49454
49534
|
throw new Error("No configured work routing candidate is ready. Install/login a candidate CLI or update chief.routing.candidates in av.yaml.");
|
|
49535
|
+
const compatible = compatibleRoutes ? candidates.filter((candidate) => compatibleRoutes.has(routeKey(candidate))) : candidates;
|
|
49536
|
+
if (!compatible.length)
|
|
49537
|
+
throw new Error("Skill compatibility required: no ready work candidate has current passing installed evidence. Refresh oma.skill_compatibility.report_path in av.yaml with explicit models before retrying.");
|
|
49455
49538
|
const evidence = routeEvidence(mission);
|
|
49456
|
-
const eligible =
|
|
49539
|
+
const eligible = compatible.filter((candidate) => {
|
|
49457
49540
|
const observed = evidence.find((item) => routeKey(item) === routeKey(candidate));
|
|
49458
49541
|
return !observed || observed.samples < routing.minSamples || observed.successes / observed.samples >= routing.minSuccessRate;
|
|
49459
49542
|
});
|
|
@@ -49515,6 +49598,10 @@ function operationsEvidence(mission) {
|
|
|
49515
49598
|
pricingBasis: "Estimates from configured input/output prices and actual adapter-reported tokens; excludes unreported cache/reasoning/subagent usage and subscription billing.",
|
|
49516
49599
|
routeQuality: routeEvidence(mission).slice(0, 20),
|
|
49517
49600
|
reviewPolicy: mission.operatingPolicy?.reviewVendor ?? "legacy independent Actor",
|
|
49601
|
+
skillCompatibility: mission.operatingPolicy?.skillCompatibility ? {
|
|
49602
|
+
mode: mission.operatingPolicy.skillCompatibility.mode,
|
|
49603
|
+
recentChecks: mission.history.filter((entry) => entry.stage === "skill-compatibility").slice(-10)
|
|
49604
|
+
} : undefined,
|
|
49518
49605
|
recentRuns: runs.slice(-20),
|
|
49519
49606
|
crossVendorReviews: mission.operations?.reviewDecisions.slice(-20) ?? [],
|
|
49520
49607
|
organizationContext: mission.organizationContext,
|
|
@@ -49530,6 +49617,10 @@ function operationsReportLines(mission) {
|
|
|
49530
49617
|
`기록된 token·설정 단가 기반 부분 비용 추정 USD ${evidence.knownEstimatedCostUsd.toFixed(6)} / 비용 미확인 ${evidence.unknownCostRuns}회 / 전체 추정 ${evidence.totalEstimatedCostUsd === null ? "미확인" : `USD ${evidence.totalEstimatedCostUsd.toFixed(6)}`}`,
|
|
49531
49618
|
`최근 독립 리뷰 배정: 다른 vendor ${evidence.crossVendorReviews.filter((review) => review.crossVendor).length}회 / 동일 vendor fallback ${evidence.crossVendorReviews.filter((review) => !review.crossVendor).length}회 / 실제 리뷰 통과 ${evidence.crossVendorReviews.filter((review) => review.outcome === "passed").length}회`,
|
|
49532
49619
|
`vendor 리뷰 정책: ${evidence.reviewPolicy}`,
|
|
49620
|
+
...evidence.skillCompatibility ? [
|
|
49621
|
+
`OMA 스킬 읽기·참조 정책: ${evidence.skillCompatibility.mode}; AV 실행 환경 또는 작업 품질 인증이 아닙니다.`,
|
|
49622
|
+
...evidence.skillCompatibility.recentChecks.map((entry) => `${entry.at}: ${entry.message}`)
|
|
49623
|
+
] : [],
|
|
49533
49624
|
...mission.organizationContext ? [
|
|
49534
49625
|
`계획·리뷰에 제공한 조직 근거: 승인 memory ${mission.organizationContext.memories.length}개 / 과거 outcome ${mission.organizationContext.outcomes.length}개 / 기록된 metric sample ${mission.organizationContext.metrics.length}개`
|
|
49535
49626
|
] : [],
|
|
@@ -49557,15 +49648,15 @@ var chiefReportSchema = strictObject({
|
|
|
49557
49648
|
checks: entries,
|
|
49558
49649
|
remaining: entries
|
|
49559
49650
|
});
|
|
49560
|
-
function
|
|
49651
|
+
function bounded2(value, limit = 500) {
|
|
49561
49652
|
const content = value.trim();
|
|
49562
49653
|
return content.length <= limit ? content : `${content.slice(0, limit - 8)}… [생략]`;
|
|
49563
49654
|
}
|
|
49564
49655
|
function compact(values, limit = 20) {
|
|
49565
49656
|
if (values.length <= limit)
|
|
49566
|
-
return values.map((value) =>
|
|
49657
|
+
return values.map((value) => bounded2(value)).filter(Boolean);
|
|
49567
49658
|
return [
|
|
49568
|
-
...values.slice(0, limit - 1).map((value) =>
|
|
49659
|
+
...values.slice(0, limit - 1).map((value) => bounded2(value)).filter(Boolean),
|
|
49569
49660
|
`${values.length - limit + 1}개 항목 생략`
|
|
49570
49661
|
];
|
|
49571
49662
|
}
|
|
@@ -49580,7 +49671,7 @@ function criteria(mission) {
|
|
|
49580
49671
|
function incompleteReasons(mission) {
|
|
49581
49672
|
const reasons = [];
|
|
49582
49673
|
if (mission.error)
|
|
49583
|
-
reasons.push(`${["waiting", "paused"].includes(mission.status) ? "대기·중단 이유" : "실패 원인"}: ${
|
|
49674
|
+
reasons.push(`${["waiting", "paused"].includes(mission.status) ? "대기·중단 이유" : "실패 원인"}: ${bounded2(mission.error, 450)}`);
|
|
49584
49675
|
if (mission.status !== "completed")
|
|
49585
49676
|
reasons.push(`미션 상태: ${mission.status}. 완료 판정이 없습니다.`);
|
|
49586
49677
|
if (!mission.verification)
|
|
@@ -49633,33 +49724,33 @@ function incompleteReasons(mission) {
|
|
|
49633
49724
|
}
|
|
49634
49725
|
function decisionEvidence(mission) {
|
|
49635
49726
|
const actions = { repair: "수정", reassign: "담당 교체", replan: "재계획", wait: "대기", stop: "중단" };
|
|
49636
|
-
return (mission.supervision?.decisions ?? []).slice(-20).map((decision) =>
|
|
49727
|
+
return (mission.supervision?.decisions ?? []).slice(-20).map((decision) => bounded2(`${decision.round}차 ${actions[decision.action]}${decision.taskId ? ` / 작업 ${decision.taskId}` : ""}${decision.personaId ? ` / 담당 ${decision.personaId}` : ""}: ${decision.reason}`));
|
|
49637
49728
|
}
|
|
49638
49729
|
function reviewEvidence(review) {
|
|
49639
49730
|
return review ? {
|
|
49640
49731
|
passed: review.passed,
|
|
49641
|
-
summary:
|
|
49732
|
+
summary: bounded2(review.summary),
|
|
49642
49733
|
findings: compact(review.findings),
|
|
49643
49734
|
criteria: review.criteria?.slice(0, 20).map((item) => ({
|
|
49644
|
-
criterion:
|
|
49735
|
+
criterion: bounded2(item.criterion),
|
|
49645
49736
|
passed: item.passed,
|
|
49646
|
-
evidence:
|
|
49737
|
+
evidence: bounded2(item.evidence)
|
|
49647
49738
|
}))
|
|
49648
49739
|
} : undefined;
|
|
49649
49740
|
}
|
|
49650
49741
|
function verificationEvidence(verification) {
|
|
49651
49742
|
return verification ? {
|
|
49652
49743
|
ok: verification.ok,
|
|
49653
|
-
output: verification.output ?
|
|
49654
|
-
fingerprint:
|
|
49744
|
+
output: verification.output ? bounded2(verification.output, 3000) : undefined,
|
|
49745
|
+
fingerprint: bounded2(verification.fingerprint, 128)
|
|
49655
49746
|
} : undefined;
|
|
49656
49747
|
}
|
|
49657
49748
|
function advisoryEvidence(kind, advisory) {
|
|
49658
49749
|
return advisory ? {
|
|
49659
49750
|
kind: `upfront ${kind} advice; historical snapshot; not current approval`,
|
|
49660
|
-
planKey:
|
|
49751
|
+
planKey: bounded2(advisory.planKey, 128),
|
|
49661
49752
|
reviewerId: advisory.reviewerId,
|
|
49662
|
-
fingerprint:
|
|
49753
|
+
fingerprint: bounded2(advisory.fingerprint, 128),
|
|
49663
49754
|
review: reviewEvidence(advisory.review)
|
|
49664
49755
|
} : undefined;
|
|
49665
49756
|
}
|
|
@@ -49669,24 +49760,24 @@ function historicalEvidence(mission) {
|
|
|
49669
49760
|
const verification = decision.evidence?.verification;
|
|
49670
49761
|
const review = decision.evidence?.finalReview;
|
|
49671
49762
|
if (verification)
|
|
49672
|
-
lines.push(
|
|
49763
|
+
lines.push(bounded2(`${decision.round}차 판단 당시 검증: ${verification.ok ? "통과" : "실패"} / 파일 상태 ${bounded2(verification.fingerprint, 128)}${verification.output ? ` / ${bounded2(verification.output, 250)}` : ""}`));
|
|
49673
49764
|
if (review) {
|
|
49674
|
-
lines.push(
|
|
49675
|
-
lines.push(...compact(review.findings, 3).map((finding) =>
|
|
49765
|
+
lines.push(bounded2(`${decision.round}차 판단 당시 최종 리뷰: ${review.passed ? "통과" : "실패"} / ${bounded2(review.summary, 350)}`));
|
|
49766
|
+
lines.push(...compact(review.findings, 3).map((finding) => bounded2(`${decision.round}차 판단 당시 지적: ${finding}`)));
|
|
49676
49767
|
}
|
|
49677
49768
|
return lines;
|
|
49678
49769
|
});
|
|
49679
49770
|
}
|
|
49680
49771
|
function checkEvidence(mission) {
|
|
49681
49772
|
return compact([
|
|
49682
|
-
`운영자 검증: ${mission.verification ? mission.verification.ok ? "통과" : "실패" : "미실행"} / 명령: ${
|
|
49773
|
+
`운영자 검증: ${mission.verification ? mission.verification.ok ? "통과" : "실패" : "미실행"} / 명령: ${bounded2(mission.supervision?.operatorVerifyCommand ?? mission.verifyCommand, 350)}`,
|
|
49683
49774
|
...mission.verification?.output ? [`검증 출력: ${mission.verification.output}`] : [],
|
|
49684
49775
|
`Chief Director 최종 리뷰: ${mission.finalReview ? mission.finalReview.passed && mission.finalReview.findings.length === 0 ? "통과" : "실패" : "미실행"}${mission.finalReview ? ` / ${mission.finalReview.summary}` : ""}`,
|
|
49685
49776
|
...mission.tasks.map((task) => `${task.id}: 상태 ${task.status}, 시도 ${task.attempts}회, 독립 리뷰 ${task.review ? task.review.passed && task.review.findings.length === 0 ? "통과" : "실패" : "미실행"} / 리뷰어 ${task.reviewerId}`)
|
|
49686
49777
|
]);
|
|
49687
49778
|
}
|
|
49688
49779
|
function criterionEvidence(mission) {
|
|
49689
|
-
return (mission.finalReview?.criteria ?? []).map((item) =>
|
|
49780
|
+
return (mission.finalReview?.criteria ?? []).map((item) => bounded2(`${bounded2(item.criterion, 200)}: ${item.passed ? "통과" : "실패"} / 근거: ${bounded2(item.evidence, 250)}`));
|
|
49690
49781
|
}
|
|
49691
49782
|
function reportPrompt(mission) {
|
|
49692
49783
|
const goal = mission.supervision?.operatorGoal ?? mission.goal;
|
|
@@ -49714,8 +49805,8 @@ function reportPrompt(mission) {
|
|
|
49714
49805
|
'{"summary":"result","eli5":"plain-language result and user impact","goalAssessment":"criteria and actual verdict","assumptions":[],"decisions":[],"deliverables":[],"checks":[],"remaining":[]}',
|
|
49715
49806
|
`Report evidence (JSON data):
|
|
49716
49807
|
${JSON.stringify({
|
|
49717
|
-
operatorGoal:
|
|
49718
|
-
interpretation: mission.goalBrief ?
|
|
49808
|
+
operatorGoal: bounded2(goal, 4000),
|
|
49809
|
+
interpretation: mission.goalBrief ? bounded2(mission.goalBrief.interpretation, 2000) : undefined,
|
|
49719
49810
|
assumptions: compact(mission.goalBrief?.assumptions ?? []),
|
|
49720
49811
|
successCriteria: compact(criteria(mission)),
|
|
49721
49812
|
status: mission.status,
|
|
@@ -49724,9 +49815,9 @@ ${JSON.stringify({
|
|
|
49724
49815
|
containerObservation: mission.containerObservation,
|
|
49725
49816
|
verdict: incompleteReasons(mission).length === 0 ? "completed" : "incomplete",
|
|
49726
49817
|
incompleteReasons: incompleteReasons(mission),
|
|
49727
|
-
error: mission.error ?
|
|
49728
|
-
workspace:
|
|
49729
|
-
branch:
|
|
49818
|
+
error: mission.error ? bounded2(mission.error, 2000) : undefined,
|
|
49819
|
+
workspace: bounded2(mission.workspace.path, 2000),
|
|
49820
|
+
branch: bounded2(mission.workspace.branch),
|
|
49730
49821
|
chiefId: mission.chiefId,
|
|
49731
49822
|
technicalLeadId: mission.technicalLeadId,
|
|
49732
49823
|
technicalAdvice: advisoryEvidence("technical", mission.technicalReview),
|
|
@@ -49736,10 +49827,10 @@ ${JSON.stringify({
|
|
|
49736
49827
|
marketingAdvice: advisoryEvidence("marketing", mission.marketingReview),
|
|
49737
49828
|
actors: mission.personas.slice(0, 20).map((persona) => ({
|
|
49738
49829
|
id: persona.id,
|
|
49739
|
-
name:
|
|
49740
|
-
role:
|
|
49741
|
-
cli:
|
|
49742
|
-
model: persona.model ?
|
|
49830
|
+
name: bounded2(persona.name),
|
|
49831
|
+
role: bounded2(persona.role),
|
|
49832
|
+
cli: bounded2(persona.agentType),
|
|
49833
|
+
model: persona.model ? bounded2(persona.model) : "native default (actual model not recorded)",
|
|
49743
49834
|
selectedSkills: persona.skills.slice(0, 30)
|
|
49744
49835
|
})),
|
|
49745
49836
|
decisions: decisions.map((decision) => ({
|
|
@@ -49747,8 +49838,8 @@ ${JSON.stringify({
|
|
|
49747
49838
|
action: decision.action,
|
|
49748
49839
|
taskId: decision.taskId,
|
|
49749
49840
|
actorId: decision.personaId,
|
|
49750
|
-
reason:
|
|
49751
|
-
instructions: decision.instructions ?
|
|
49841
|
+
reason: bounded2(decision.reason),
|
|
49842
|
+
instructions: decision.instructions ? bounded2(decision.instructions) : undefined,
|
|
49752
49843
|
historicalEvidence: decision.evidence && snapshotDecisions.has(decision) ? {
|
|
49753
49844
|
kind: "evidence at the recovery decision; not current approval",
|
|
49754
49845
|
finalReview: reviewEvidence(decision.evidence.finalReview),
|
|
@@ -49757,25 +49848,25 @@ ${JSON.stringify({
|
|
|
49757
49848
|
})),
|
|
49758
49849
|
tasks: mission.tasks.slice(0, 12).map((state) => ({
|
|
49759
49850
|
id: state.id,
|
|
49760
|
-
title:
|
|
49851
|
+
title: bounded2(mission.plan?.tasks.find((task) => task.id === state.id)?.title ?? state.id),
|
|
49761
49852
|
actorId: mission.plan?.tasks.find((task) => task.id === state.id)?.personaId,
|
|
49762
49853
|
reviewerId: state.reviewerId,
|
|
49763
49854
|
status: state.status,
|
|
49764
49855
|
attempts: state.attempts,
|
|
49765
|
-
actorClaim: state.output ?
|
|
49856
|
+
actorClaim: state.output ? bounded2(state.output, 3000) : undefined,
|
|
49766
49857
|
review: reviewEvidence(state.review)
|
|
49767
49858
|
})),
|
|
49768
|
-
verifyCommand:
|
|
49859
|
+
verifyCommand: bounded2(mission.supervision?.operatorVerifyCommand ?? mission.verifyCommand, 1200),
|
|
49769
49860
|
verification: verificationEvidence(mission.verification),
|
|
49770
49861
|
goalVerification: mission.goalVerification,
|
|
49771
49862
|
execution: mission.execution,
|
|
49772
49863
|
executionPolicy: mission.executionPolicy,
|
|
49773
49864
|
finalReview: reviewEvidence(mission.finalReview),
|
|
49774
49865
|
history: mission.history.slice(-30).map((event) => ({
|
|
49775
|
-
at:
|
|
49776
|
-
stage:
|
|
49866
|
+
at: bounded2(event.at),
|
|
49867
|
+
stage: bounded2(event.stage),
|
|
49777
49868
|
taskId: event.taskId,
|
|
49778
|
-
message:
|
|
49869
|
+
message: bounded2(event.message)
|
|
49779
49870
|
}))
|
|
49780
49871
|
})}`
|
|
49781
49872
|
].join(`
|
|
@@ -49797,10 +49888,10 @@ function parseReport(source) {
|
|
|
49797
49888
|
function fallbackReport(mission) {
|
|
49798
49889
|
const reasons = incompleteReasons(mission);
|
|
49799
49890
|
const complete = reasons.length === 0;
|
|
49800
|
-
const goal =
|
|
49891
|
+
const goal = bounded2(mission.supervision?.operatorGoal ?? mission.goal, 350);
|
|
49801
49892
|
return {
|
|
49802
49893
|
summary: complete ? "작업, 독립 리뷰, 운영자 검증과 Chief Director 최종 리뷰를 통과했습니다." : "목표는 미완료입니다. 확인된 미해결 조건과 보관된 실행 기록을 보고합니다.",
|
|
49803
|
-
eli5: complete ? `“${goal}”을 위한 결과물을 만들고, 다른 담당자의 점검과 지정한 확인 절차를 마쳤습니다. 결과물은 아래 작업 경로에 보관되어 있어 직접 확인할 수 있습니다.` : `“${goal}”을 위해 작업했지만, 아직 모든 확인 절차를 통과한 결과는 아닙니다. ${
|
|
49894
|
+
eli5: complete ? `“${goal}”을 위한 결과물을 만들고, 다른 담당자의 점검과 지정한 확인 절차를 마쳤습니다. 결과물은 아래 작업 경로에 보관되어 있어 직접 확인할 수 있습니다.` : `“${goal}”을 위해 작업했지만, 아직 모든 확인 절차를 통과한 결과는 아닙니다. ${bounded2(reasons[0] ?? "완료 증거가 없습니다.", 350)} 이미 만든 작업은 보관되어 있습니다. Chief Director가 기록한 판단과 다음 관측·재개 시각, 아직 충족되지 않은 조건을 아래에서 보고합니다.`,
|
|
49804
49895
|
goalAssessment: complete ? "기록된 성공 기준에 대해 작업별 독립 리뷰와 운영자 검증이 통과했고, Chief Director가 최종 승인했습니다." : "성공 기준 전체의 충족을 확인하지 못했습니다. 일부 작업이나 검증이 통과했더라도 목표 달성으로 표시하지 않습니다.",
|
|
49805
49896
|
assumptions: compact(mission.goalBrief?.assumptions ?? []),
|
|
49806
49897
|
decisions: decisionEvidence(mission),
|
|
@@ -49818,7 +49909,7 @@ function fallbackReport(mission) {
|
|
|
49818
49909
|
};
|
|
49819
49910
|
}
|
|
49820
49911
|
function markdown(value, limit = 1200) {
|
|
49821
|
-
return
|
|
49912
|
+
return bounded2(value, limit).replace(/[\p{Cc}\p{Cf}]/gu, " ").replace(/\s+/g, " ").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/[\\`*_{}[\]()#+.!|~-]/g, "\\$&");
|
|
49822
49913
|
}
|
|
49823
49914
|
function list(values) {
|
|
49824
49915
|
return values.length ? compact(values).map((value) => `- ${markdown(value)}`).join(`
|
|
@@ -50333,12 +50424,12 @@ async function assertMissionWorkspace(mission) {
|
|
|
50333
50424
|
}
|
|
50334
50425
|
|
|
50335
50426
|
// ../../packages/core/src/chief/parallel-workspace.ts
|
|
50336
|
-
var
|
|
50427
|
+
var hash2 = (value) => createHash10("sha256").update(value).digest("hex");
|
|
50337
50428
|
var same = (a, b) => JSON.stringify(a) === JSON.stringify(b);
|
|
50338
50429
|
function identity3(missionId, taskId, attempt) {
|
|
50339
50430
|
if (!taskId || taskId.length > 200 || !Number.isSafeInteger(attempt) || attempt < 1)
|
|
50340
50431
|
throw new Error("Use a valid task ID and positive attempt number for each parallel Actor.");
|
|
50341
|
-
return `${
|
|
50432
|
+
return `${hash2(missionId).slice(0, 16)}-${hash2(taskId).slice(0, 16)}-${attempt}`;
|
|
50342
50433
|
}
|
|
50343
50434
|
async function paths(source, missionId, taskId, attempt) {
|
|
50344
50435
|
const root = await parallelRoot(source);
|
|
@@ -50482,7 +50573,7 @@ async function collectTaskDelivery(mission, workspace) {
|
|
|
50482
50573
|
version: 1,
|
|
50483
50574
|
workspace,
|
|
50484
50575
|
patchPath: location.patch,
|
|
50485
|
-
patchSha256:
|
|
50576
|
+
patchSha256: hash2(patch),
|
|
50486
50577
|
deliveryTree: final.tree,
|
|
50487
50578
|
changes,
|
|
50488
50579
|
status: "prepared"
|
|
@@ -50498,7 +50589,7 @@ async function integrateTaskDelivery(mission, input) {
|
|
|
50498
50589
|
if (delivery.workspace.missionId !== mission.id || !same(delivery.workspace, input.workspace) || delivery.patchSha256 !== input.patchSha256 || delivery.patchPath !== location.patch)
|
|
50499
50590
|
throw new Error("Parallel delivery does not match its persisted task identity and patch. Inspect the saved artifacts before recovery.");
|
|
50500
50591
|
const patch = await readFile4(location.patch);
|
|
50501
|
-
if (
|
|
50592
|
+
if (hash2(patch) !== delivery.patchSha256)
|
|
50502
50593
|
throw new Error("Parallel delivery patch changed. Restore its saved SHA256 before integration.");
|
|
50503
50594
|
const current = await captureParallelBaseline(mission.workspace.path);
|
|
50504
50595
|
const images = await parallelTreeImages(mission.workspace.path, current.tree);
|
|
@@ -66141,7 +66232,11 @@ ${details}` : ""}`);
|
|
|
66141
66232
|
timeoutSec,
|
|
66142
66233
|
maxRepairs,
|
|
66143
66234
|
maxRounds,
|
|
66144
|
-
operatingPolicy: chiefOperatingPolicy(chiefConfig, readyActors, !profile
|
|
66235
|
+
operatingPolicy: chiefOperatingPolicy(chiefConfig, readyActors, !profile, project?.oma?.skill_compatibility ? {
|
|
66236
|
+
reportPath: resolve11(root, project.oma.skill_compatibility.report_path),
|
|
66237
|
+
maxAgeHours: project.oma.skill_compatibility.max_age_hours,
|
|
66238
|
+
mode: project.oma.skill_compatibility.mode
|
|
66239
|
+
} : undefined),
|
|
66145
66240
|
capturePolicy: chiefCapturePolicy(chiefConfig),
|
|
66146
66241
|
executionPolicy,
|
|
66147
66242
|
metricSourcePolicy: chiefConfig.metric_sources,
|
|
@@ -66676,7 +66771,7 @@ class ContinuousOperationStore {
|
|
|
66676
66771
|
}
|
|
66677
66772
|
|
|
66678
66773
|
// src/chief-continuous.ts
|
|
66679
|
-
import { execFile as
|
|
66774
|
+
import { execFile as execFile5 } from "node:child_process";
|
|
66680
66775
|
import { randomUUID as randomUUID15 } from "node:crypto";
|
|
66681
66776
|
import { mkdir as mkdir17, realpath as realpath19, rename as rename7, unlink as unlink7, writeFile as writeFile13 } from "node:fs/promises";
|
|
66682
66777
|
import { join as join35, resolve as resolve19 } from "node:path";
|
|
@@ -68307,6 +68402,214 @@ function validateOmaEvidence(request, io = defaultIO2) {
|
|
|
68307
68402
|
return { ok: true, runId: String(run.runId) };
|
|
68308
68403
|
}
|
|
68309
68404
|
|
|
68405
|
+
// ../../packages/core/src/oma/skill-matrix-adapter.ts
|
|
68406
|
+
import { posix } from "node:path";
|
|
68407
|
+
|
|
68408
|
+
// ../../packages/core/src/oma/skill-matrix-io.ts
|
|
68409
|
+
init_skill_matrix_schema();
|
|
68410
|
+
import { execFile as execFile4 } from "node:child_process";
|
|
68411
|
+
import { constants as constants5 } from "node:fs";
|
|
68412
|
+
import { open as open7 } from "node:fs/promises";
|
|
68413
|
+
var MAX_BYTES = 4 * 1024 * 1024;
|
|
68414
|
+
async function command(binary, args, signal) {
|
|
68415
|
+
return new Promise((resolve, reject) => {
|
|
68416
|
+
execFile4(binary, args, {
|
|
68417
|
+
encoding: "utf8",
|
|
68418
|
+
timeout: 1e4,
|
|
68419
|
+
maxBuffer: MAX_BYTES,
|
|
68420
|
+
signal,
|
|
68421
|
+
...binary === "oma" ? { env: { ...process.env, OMA_SKIP_VERSION_CHECK: "1" } } : {}
|
|
68422
|
+
}, (error, stdout) => {
|
|
68423
|
+
if (error)
|
|
68424
|
+
reject(new Error(`${binary} local diagnostic command failed. Check its installation/version and retry.`));
|
|
68425
|
+
else
|
|
68426
|
+
resolve(stdout);
|
|
68427
|
+
});
|
|
68428
|
+
});
|
|
68429
|
+
}
|
|
68430
|
+
async function readReport(path) {
|
|
68431
|
+
const file = await open7(path, constants5.O_RDONLY | constants5.O_NOFOLLOW | constants5.O_NONBLOCK);
|
|
68432
|
+
try {
|
|
68433
|
+
const info = await file.stat();
|
|
68434
|
+
if (!info.isFile() || info.size > MAX_BYTES)
|
|
68435
|
+
throw new Error("Matrix report must be a regular file at most 4 MiB.");
|
|
68436
|
+
const bytes = Buffer.alloc(info.size + 1);
|
|
68437
|
+
let length = 0;
|
|
68438
|
+
while (length < bytes.length) {
|
|
68439
|
+
const result = await file.read(bytes, length, bytes.length - length, length);
|
|
68440
|
+
if (!result.bytesRead)
|
|
68441
|
+
break;
|
|
68442
|
+
length += result.bytesRead;
|
|
68443
|
+
}
|
|
68444
|
+
if (length !== info.size)
|
|
68445
|
+
throw new Error("Matrix report changed during the read. Retry after its writer finishes.");
|
|
68446
|
+
return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(0, length)));
|
|
68447
|
+
} finally {
|
|
68448
|
+
await file.close();
|
|
68449
|
+
}
|
|
68450
|
+
}
|
|
68451
|
+
var defaultSkillMatrixDeps = {
|
|
68452
|
+
now: Date.now,
|
|
68453
|
+
platform: process.platform,
|
|
68454
|
+
arch: process.arch,
|
|
68455
|
+
readReport,
|
|
68456
|
+
plan: async (workspace, skills, signal) => JSON.parse(await command("oma", [
|
|
68457
|
+
"skills",
|
|
68458
|
+
"matrix",
|
|
68459
|
+
"--project-root",
|
|
68460
|
+
workspace,
|
|
68461
|
+
"--skills",
|
|
68462
|
+
skills.join(","),
|
|
68463
|
+
"--delivery",
|
|
68464
|
+
"injected",
|
|
68465
|
+
"--vendors",
|
|
68466
|
+
"claude,codex",
|
|
68467
|
+
"--json"
|
|
68468
|
+
], signal)),
|
|
68469
|
+
cliVersion: async (vendor, signal) => {
|
|
68470
|
+
const version = (await command(vendor, ["--version"], signal)).trim();
|
|
68471
|
+
return /^[\w .()+/-]{1,160}$/.test(version) ? version : null;
|
|
68472
|
+
}
|
|
68473
|
+
};
|
|
68474
|
+
function parseSkillMatrix(value) {
|
|
68475
|
+
const parsed = matrixReportSchema.safeParse(value);
|
|
68476
|
+
if (!parsed.success)
|
|
68477
|
+
throw new Error("Matrix report uses an unsupported or malformed evidence contract. Regenerate it with the current OMA CLI.");
|
|
68478
|
+
const report = parsed.data;
|
|
68479
|
+
const unique = (values) => new Set(values).size === values.length;
|
|
68480
|
+
if (!unique(report.cases.map((entry) => entry.id)) || !unique(report.cells.map((entry) => `${entry.vendor}\x00${entry.caseId}`)) || report.bundle && (!unique(report.bundle.skills.map((entry) => entry.name)) || !unique(report.bundle.skills.map((entry) => entry.caseId))) || report.cells.some((cell) => !unique(cell.checks.map((check) => check.id))))
|
|
68481
|
+
throw new Error("Matrix report repeats a skill, case or vendor cell. Regenerate an unambiguous report.");
|
|
68482
|
+
return report;
|
|
68483
|
+
}
|
|
68484
|
+
|
|
68485
|
+
// ../../packages/core/src/oma/skill-matrix-adapter.ts
|
|
68486
|
+
var scope = "installed injected read-reference audit; not AV runtime or task-quality certification";
|
|
68487
|
+
var safeNames = /^[a-z0-9][a-z0-9-]{0,127}$/;
|
|
68488
|
+
var remediation = "Regenerate the installed injected matrix with explicit models, then set oma.skill_compatibility.report_path in av.yaml.";
|
|
68489
|
+
var matrixRouteKey = (route) => `${route.actorType}\x00${route.model ?? ""}`;
|
|
68490
|
+
function sourceProblem(report) {
|
|
68491
|
+
if (report.sourceKind !== "installed" || report.delivery !== "injected" || report.auditScope !== "read-reference" || !report.bundle)
|
|
68492
|
+
return "Evidence is not an installed, injected, read-reference audit. Synthetic probes cannot authorize installed skills.";
|
|
68493
|
+
return;
|
|
68494
|
+
}
|
|
68495
|
+
function sameCoverage(a, b) {
|
|
68496
|
+
const sorted = (items) => JSON.stringify([...items].sort());
|
|
68497
|
+
return a.hash === b.hash && a.caseId === b.caseId && sorted(a.requiredFiles) === sorted(b.requiredFiles) && sorted(a.missingFiles) === sorted(b.missingFiles) && JSON.stringify(a.excludedReferences) === JSON.stringify(b.excludedReferences);
|
|
68498
|
+
}
|
|
68499
|
+
function assessRoute(report, plan, skills, route, version) {
|
|
68500
|
+
const result = (status, reason) => ({
|
|
68501
|
+
...route,
|
|
68502
|
+
status,
|
|
68503
|
+
reason
|
|
68504
|
+
});
|
|
68505
|
+
if (route.actorType !== "claude" && route.actorType !== "codex")
|
|
68506
|
+
return result("unknown", "This matrix protocol measures only Claude and Codex.");
|
|
68507
|
+
if (!route.model)
|
|
68508
|
+
return result("unknown", "The candidate uses an unpinned native model default; it cannot match a measured model.");
|
|
68509
|
+
if (!version)
|
|
68510
|
+
return result("unknown", "The current native CLI version could not be verified.");
|
|
68511
|
+
for (const name of skills) {
|
|
68512
|
+
const current = plan.bundle?.skills.find((entry) => entry.name === name);
|
|
68513
|
+
const saved = report.bundle?.skills.find((entry) => entry.name === name);
|
|
68514
|
+
if (!current || !saved)
|
|
68515
|
+
return result("unknown", `Skill ${name} has no complete installed audit coverage.`);
|
|
68516
|
+
if (!sameCoverage(current, saved))
|
|
68517
|
+
return result("unknown", `Skill ${name} content or reference coverage changed after the audit.`);
|
|
68518
|
+
if (current.missingFiles.length || current.excludedReferences.length || saved.missingFiles.length || saved.excludedReferences.length)
|
|
68519
|
+
return result("unknown", `Skill ${name} has missing or excluded references; complete its audit coverage first.`);
|
|
68520
|
+
if (!report.cases.some((entry) => entry.id === saved.caseId && entry.skill === name))
|
|
68521
|
+
return result("unknown", `Skill ${name} required case is absent from the measured selection.`);
|
|
68522
|
+
const cell = report.cells.find((entry) => entry.caseId === saved.caseId && entry.vendor === route.actorType);
|
|
68523
|
+
if (!cell || cell.skill !== name || cell.contentHash !== current.hash)
|
|
68524
|
+
return result("unknown", `Skill ${name} lacks a matching measured vendor cell.`);
|
|
68525
|
+
if (cell.cliVersion !== version)
|
|
68526
|
+
return result("unknown", `Skill ${name} was measured with a different or unknown native CLI version.`);
|
|
68527
|
+
if (cell.model !== route.model)
|
|
68528
|
+
return result("unknown", `Skill ${name} was measured with a different or unknown reported model.`);
|
|
68529
|
+
if (cell.status !== "pass" || !cell.checks.length || cell.checks.some((check) => check.status !== "pass"))
|
|
68530
|
+
return result(cell.status === "fail" ? "fail" : "unknown", `Skill ${name} audit is ${cell.status}; passing read-reference evidence is required.`);
|
|
68531
|
+
const entry = `${name}/SKILL.md`;
|
|
68532
|
+
if (!current.requiredFiles.includes(entry))
|
|
68533
|
+
return result("unknown", `Skill ${name} audit omits its installed SKILL.md.`);
|
|
68534
|
+
const required = [
|
|
68535
|
+
"process",
|
|
68536
|
+
"output",
|
|
68537
|
+
"content",
|
|
68538
|
+
"integrity",
|
|
68539
|
+
"reference-coverage",
|
|
68540
|
+
...current.requiredFiles.filter((file) => file !== entry).map((file) => `reference:${posix.relative(name, file)}`)
|
|
68541
|
+
];
|
|
68542
|
+
if (required.some((id) => !cell.checks.some((check) => check.id === id && check.status === "pass" && (id === "content" || id.startsWith("reference:") ? check.proof === "read" : true))))
|
|
68543
|
+
return result("unknown", `Skill ${name} audit lacks a mandatory successful read-reference check.`);
|
|
68544
|
+
}
|
|
68545
|
+
return result("pass", "All selected skills have current passing installed injected read-reference evidence.");
|
|
68546
|
+
}
|
|
68547
|
+
async function inspectSkillCompatibility(policy, workspace, selectedSkills, routes, deps = defaultSkillMatrixDeps, signal) {
|
|
68548
|
+
const unknown = (reason) => ({
|
|
68549
|
+
scope,
|
|
68550
|
+
routes: routes.map((route) => ({ ...route, status: "unknown", reason }))
|
|
68551
|
+
});
|
|
68552
|
+
if (selectedSkills?.length === 0)
|
|
68553
|
+
return {
|
|
68554
|
+
scope,
|
|
68555
|
+
routes: routes.map((route) => ({
|
|
68556
|
+
...route,
|
|
68557
|
+
status: "pass",
|
|
68558
|
+
reason: "No skills selected; no compatibility claim is required."
|
|
68559
|
+
}))
|
|
68560
|
+
};
|
|
68561
|
+
try {
|
|
68562
|
+
if (signal?.aborted)
|
|
68563
|
+
throw new Error("Interrupted");
|
|
68564
|
+
const report = parseSkillMatrix(await deps.readReport(policy.reportPath));
|
|
68565
|
+
const source = sourceProblem(report);
|
|
68566
|
+
if (source)
|
|
68567
|
+
return unknown(source);
|
|
68568
|
+
if (report.mode !== "live" || report.status !== "completed")
|
|
68569
|
+
return unknown("The report is not a completed live measurement; a plan is unmeasured.");
|
|
68570
|
+
const age = deps.now() - Date.parse(report.createdAt);
|
|
68571
|
+
if (age < -60000 || age > policy.maxAgeHours * 3600000)
|
|
68572
|
+
return unknown("The cached matrix is stale or has a future timestamp.");
|
|
68573
|
+
if (report.host.platform !== deps.platform || report.host.arch !== deps.arch)
|
|
68574
|
+
return unknown("The matrix host platform or architecture differs from this runtime.");
|
|
68575
|
+
const skills = [...new Set(selectedSkills ?? report.bundle?.skills.map((entry) => entry.name) ?? [])];
|
|
68576
|
+
if (!skills.length || skills.length > 100 || skills.some((name) => !safeNames.test(name)))
|
|
68577
|
+
return unknown("Select a bounded list of valid installed skill names.");
|
|
68578
|
+
const plan = parseSkillMatrix(await deps.plan(workspace, skills, signal));
|
|
68579
|
+
if (sourceProblem(plan) || plan.mode !== "plan" || plan.status !== "planned")
|
|
68580
|
+
return unknown("OMA did not return a supported installed injected plan.");
|
|
68581
|
+
if (plan.omaVersion !== report.omaVersion)
|
|
68582
|
+
return unknown("The OMA version changed after measurement; refresh the cached matrix.");
|
|
68583
|
+
if (plan.host.platform !== deps.platform || plan.host.arch !== deps.arch)
|
|
68584
|
+
return unknown("The current OMA plan host does not match this runtime.");
|
|
68585
|
+
const versions = new Map;
|
|
68586
|
+
for (const route of routes) {
|
|
68587
|
+
if (versions.has(route.actorType) || route.actorType !== "claude" && route.actorType !== "codex")
|
|
68588
|
+
continue;
|
|
68589
|
+
try {
|
|
68590
|
+
versions.set(route.actorType, await deps.cliVersion(route.actorType, signal));
|
|
68591
|
+
} catch {
|
|
68592
|
+
versions.set(route.actorType, null);
|
|
68593
|
+
}
|
|
68594
|
+
}
|
|
68595
|
+
if (signal?.aborted)
|
|
68596
|
+
throw new Error("Interrupted");
|
|
68597
|
+
return {
|
|
68598
|
+
scope,
|
|
68599
|
+
routes: routes.map((route) => assessRoute(report, plan, skills, route, versions.get(route.actorType) ?? null))
|
|
68600
|
+
};
|
|
68601
|
+
} catch {
|
|
68602
|
+
if (signal?.aborted)
|
|
68603
|
+
throw new Error("Skill compatibility inspection interrupted before Actor launch.");
|
|
68604
|
+
return unknown(`The cached report or local OMA plan could not be validated. ${remediation}`);
|
|
68605
|
+
}
|
|
68606
|
+
}
|
|
68607
|
+
function assertCompatibleRoute(route, inspection) {
|
|
68608
|
+
const result = inspection.routes.find((entry) => matrixRouteKey(entry) === matrixRouteKey(route));
|
|
68609
|
+
if (result?.status !== "pass")
|
|
68610
|
+
throw new Error(`Skill compatibility required for ${route.actorType}/${route.model ?? "native default"}: ${result?.reason ?? "no matching evidence"} ${remediation}`);
|
|
68611
|
+
}
|
|
68612
|
+
|
|
68310
68613
|
// ../../packages/core/src/orchestrator/agent-runner.ts
|
|
68311
68614
|
init_logger();
|
|
68312
68615
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -68798,8 +69101,8 @@ async function withMissionDeadline(mission, parent, run) {
|
|
|
68798
69101
|
|
|
68799
69102
|
// ../../packages/core/src/chief/skills.ts
|
|
68800
69103
|
init_dist();
|
|
68801
|
-
import { constants as
|
|
68802
|
-
import { lstat as lstat11, mkdir as mkdir13, open as
|
|
69104
|
+
import { constants as constants6 } from "node:fs";
|
|
69105
|
+
import { lstat as lstat11, mkdir as mkdir13, open as open8, readdir as readdir6, realpath as realpath14, stat, writeFile as writeFile10 } from "node:fs/promises";
|
|
68803
69106
|
import { isAbsolute as isAbsolute8, join as join26, relative as relative8, sep as sep10 } from "node:path";
|
|
68804
69107
|
var MAX_SKILL_BYTES = 256000;
|
|
68805
69108
|
var MAX_METADATA_BYTES = 16384;
|
|
@@ -68880,7 +69183,7 @@ async function prepareMissionSkills(sourceRepositoryPath, workspacePath) {
|
|
|
68880
69183
|
const parent = await realpath14(targetDirectory);
|
|
68881
69184
|
if (parent !== destinationRoot && !inside(destinationRoot, parent))
|
|
68882
69185
|
throw new Error("A target skill resource escapes the mission worktree. Fix its symlink before creating this order.");
|
|
68883
|
-
const file = await
|
|
69186
|
+
const file = await open8(from, constants6.O_RDONLY | constants6.O_NOFOLLOW | constants6.O_NONBLOCK);
|
|
68884
69187
|
try {
|
|
68885
69188
|
const current = await file.stat();
|
|
68886
69189
|
if (!current.isFile())
|
|
@@ -68941,7 +69244,7 @@ async function skillPath(root, name) {
|
|
|
68941
69244
|
return path;
|
|
68942
69245
|
}
|
|
68943
69246
|
async function readSkill(path, metadataOnly) {
|
|
68944
|
-
const file = await
|
|
69247
|
+
const file = await open8(path, constants6.O_RDONLY | constants6.O_NOFOLLOW | constants6.O_NONBLOCK);
|
|
68945
69248
|
try {
|
|
68946
69249
|
const info = await file.stat();
|
|
68947
69250
|
if (!info.isFile())
|
|
@@ -69169,11 +69472,13 @@ class ChiefRuntime {
|
|
|
69169
69472
|
store;
|
|
69170
69473
|
signal;
|
|
69171
69474
|
onStage;
|
|
69475
|
+
skillMatrixDeps;
|
|
69172
69476
|
runners = new Set;
|
|
69173
|
-
constructor(store, signal, onStage = () => {}) {
|
|
69477
|
+
constructor(store, signal, onStage = () => {}, skillMatrixDeps) {
|
|
69174
69478
|
this.store = store;
|
|
69175
69479
|
this.signal = signal;
|
|
69176
69480
|
this.onStage = onStage;
|
|
69481
|
+
this.skillMatrixDeps = skillMatrixDeps;
|
|
69177
69482
|
}
|
|
69178
69483
|
ports() {
|
|
69179
69484
|
return {
|
|
@@ -69249,8 +69554,22 @@ class ChiefRuntime {
|
|
|
69249
69554
|
};
|
|
69250
69555
|
if (signal?.aborted)
|
|
69251
69556
|
throw new Error("Order interrupted. Resume it with av order --resume followed by its mission ID.");
|
|
69252
|
-
const
|
|
69557
|
+
const compatibilityPolicy = mission.operatingPolicy?.skillCompatibility;
|
|
69558
|
+
const compatibility = stage === "work" && compatibilityPolicy ? await inspectSkillCompatibility(compatibilityPolicy, workspace.path, persona.skills, workActorCandidates(mission, persona, compatibilityPolicy.mode === "require"), this.skillMatrixDeps, signal) : undefined;
|
|
69559
|
+
const compatibleRoutes = compatibilityPolicy?.mode === "require" && compatibility ? new Set(compatibility.routes.filter((entry) => entry.status === "pass").map(matrixRouteKey)) : undefined;
|
|
69560
|
+
if (compatibility && compatibilityPolicy)
|
|
69561
|
+
mission.history.push({
|
|
69562
|
+
at: new Date().toISOString(),
|
|
69563
|
+
stage: "skill-compatibility",
|
|
69564
|
+
message: `${compatibilityPolicy.mode}: ${compatibility.routes.map((entry) => `${entry.actorType}/${entry.model ?? "native default"} ${entry.status}: ${entry.reason}`).join("; ")} Scope: ${compatibility.scope}.`,
|
|
69565
|
+
...context?.taskId ? { taskId: context.taskId } : {}
|
|
69566
|
+
});
|
|
69567
|
+
const route = stage === "work" ? selectWorkActor(mission, persona, context?.taskId, compatibleRoutes) : undefined;
|
|
69253
69568
|
persona = route?.actor ?? persona;
|
|
69569
|
+
if (compatibility && compatibilityPolicy) {
|
|
69570
|
+
if (compatibilityPolicy.mode === "require")
|
|
69571
|
+
assertCompatibleRoute({ actorType: persona.agentType, model: persona.model }, compatibility);
|
|
69572
|
+
}
|
|
69254
69573
|
this.onStage(stage, persona);
|
|
69255
69574
|
const attempt = {
|
|
69256
69575
|
id: randomUUID11(),
|
|
@@ -69852,19 +70171,19 @@ init_report_delivery_contract();
|
|
|
69852
70171
|
init_zod();
|
|
69853
70172
|
init_report_delivery_contract();
|
|
69854
70173
|
import { createHash as createHash16, randomUUID as randomUUID12 } from "node:crypto";
|
|
69855
|
-
import { constants as
|
|
69856
|
-
import { mkdir as mkdir14, open as
|
|
70174
|
+
import { constants as constants7 } from "node:fs";
|
|
70175
|
+
import { mkdir as mkdir14, open as open9, readdir as readdir7, readFile as readFile11, realpath as realpath15, rename as rename6, unlink as unlink5, writeFile as writeFile11 } from "node:fs/promises";
|
|
69857
70176
|
import { isAbsolute as isAbsolute9, join as join28, relative as relative9, resolve as resolve16 } from "node:path";
|
|
69858
|
-
var
|
|
70177
|
+
var hash3 = string2().regex(/^[a-f0-9]{64}$/);
|
|
69859
70178
|
var outboxRecordSchema = strictObject({
|
|
69860
70179
|
version: literal(1),
|
|
69861
|
-
id:
|
|
70180
|
+
id: hash3,
|
|
69862
70181
|
missionId: string2().regex(/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/),
|
|
69863
70182
|
missionStatus: _enum(["completed", "failed"]),
|
|
69864
70183
|
destinationId: string2().regex(/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/),
|
|
69865
70184
|
channel: string2().regex(/^[a-z][a-z0-9-]{0,63}$/),
|
|
69866
|
-
reportHash:
|
|
69867
|
-
destinationHash:
|
|
70185
|
+
reportHash: hash3,
|
|
70186
|
+
destinationHash: hash3.optional(),
|
|
69868
70187
|
goal: string2().max(32000),
|
|
69869
70188
|
markdown: string2().max(256000),
|
|
69870
70189
|
reportPath: string2().max(4096),
|
|
@@ -69899,7 +70218,7 @@ class ReportOutbox {
|
|
|
69899
70218
|
this.directory = join28(stateDir, "report-outbox");
|
|
69900
70219
|
}
|
|
69901
70220
|
path(id) {
|
|
69902
|
-
if (!
|
|
70221
|
+
if (!hash3.safeParse(id).success)
|
|
69903
70222
|
throw new Error("Invalid report receipt ID. Use av reports to find a receipt.");
|
|
69904
70223
|
return join28(this.directory, `${id}.json`);
|
|
69905
70224
|
}
|
|
@@ -69962,7 +70281,7 @@ async function verifiedAttachment(attachment, artifactRoot, readBytes) {
|
|
|
69962
70281
|
throw failure;
|
|
69963
70282
|
if (resolve16(attachment.path) !== attachment.path)
|
|
69964
70283
|
throw failure;
|
|
69965
|
-
const file = await
|
|
70284
|
+
const file = await open9(attachment.path, constants7.O_RDONLY | constants7.O_NOFOLLOW);
|
|
69966
70285
|
try {
|
|
69967
70286
|
const stat = await file.stat();
|
|
69968
70287
|
if (!stat.isFile() || stat.size !== attachment.sizeBytes)
|
|
@@ -70497,8 +70816,8 @@ Return one valid JSON object under the original charter and pinned evidence.` :
|
|
|
70497
70816
|
|
|
70498
70817
|
// ../../packages/core/src/chief/metric-source-adapters.ts
|
|
70499
70818
|
init_metric_source_policy();
|
|
70500
|
-
import { constants as
|
|
70501
|
-
import { lstat as lstat12, open as
|
|
70819
|
+
import { constants as constants8 } from "node:fs";
|
|
70820
|
+
import { lstat as lstat12, open as open10, realpath as realpath16 } from "node:fs/promises";
|
|
70502
70821
|
import { isAbsolute as isAbsolute10, relative as relative10, resolve as resolve17, sep as sep11 } from "node:path";
|
|
70503
70822
|
var MAX_METRIC_RESPONSE_BYTES = 2000000;
|
|
70504
70823
|
function metricSourceEnvironment(request, name) {
|
|
@@ -70596,7 +70915,7 @@ var jsonFileMetricAdapter = {
|
|
|
70596
70915
|
if ((await lstat12(current)).isSymbolicLink())
|
|
70597
70916
|
throw new MetricSourceError("Metric file and parent directories must not be symlinks. Choose a regular JSON file inside the source repository.");
|
|
70598
70917
|
}
|
|
70599
|
-
const file = await
|
|
70918
|
+
const file = await open10(path, constants8.O_RDONLY | constants8.O_NOFOLLOW);
|
|
70600
70919
|
try {
|
|
70601
70920
|
const stat = await file.stat();
|
|
70602
70921
|
if (!stat.isFile() || stat.size > MAX_METRIC_RESPONSE_BYTES || await realpath16(path) !== path)
|
|
@@ -70997,8 +71316,8 @@ function createMissionMetricPorts(repository, mission, dependencies = {}) {
|
|
|
70997
71316
|
|
|
70998
71317
|
// src/chief-tool-config.ts
|
|
70999
71318
|
import { randomUUID as randomUUID14 } from "node:crypto";
|
|
71000
|
-
import { constants as
|
|
71001
|
-
import { link as link2, lstat as lstat13, mkdir as mkdir16, open as
|
|
71319
|
+
import { constants as constants9 } from "node:fs";
|
|
71320
|
+
import { link as link2, lstat as lstat13, mkdir as mkdir16, open as open11, realpath as realpath17, unlink as unlink6 } from "node:fs/promises";
|
|
71002
71321
|
import { join as join32 } from "node:path";
|
|
71003
71322
|
init_dist2();
|
|
71004
71323
|
init_client_toml();
|
|
@@ -71032,7 +71351,7 @@ async function assertLocalPath(root, local) {
|
|
|
71032
71351
|
return true;
|
|
71033
71352
|
}
|
|
71034
71353
|
async function readPrivateFile(path) {
|
|
71035
|
-
const file = await
|
|
71354
|
+
const file = await open11(path, constants9.O_RDONLY | constants9.O_NOFOLLOW);
|
|
71036
71355
|
try {
|
|
71037
71356
|
const stats = await file.stat();
|
|
71038
71357
|
if (!stats.isFile() || stats.size > maximumBytes)
|
|
@@ -71095,7 +71414,7 @@ async function privateExclude(original, target, paths) {
|
|
|
71095
71414
|
const patterns = paths.flatMap((local) => [`/${local}`, `/${local}.av-mcp-*.tmp`]).filter((pattern) => !lines.has(pattern));
|
|
71096
71415
|
if (!patterns.length)
|
|
71097
71416
|
return;
|
|
71098
|
-
const file = await
|
|
71417
|
+
const file = await open11(path, constants9.O_WRONLY | constants9.O_APPEND | constants9.O_CREAT | constants9.O_NOFOLLOW, 384);
|
|
71099
71418
|
try {
|
|
71100
71419
|
await file.writeFile(`${content && !content.endsWith(`
|
|
71101
71420
|
`) ? `
|
|
@@ -71140,7 +71459,7 @@ async function prepareToolConfig(originalRepository, targetWorkspace) {
|
|
|
71140
71459
|
continue;
|
|
71141
71460
|
const path = join32(target, config.path);
|
|
71142
71461
|
const temporary = `${path}.av-mcp-${randomUUID14()}.tmp`;
|
|
71143
|
-
const file = await
|
|
71462
|
+
const file = await open11(temporary, "wx", 384);
|
|
71144
71463
|
try {
|
|
71145
71464
|
await file.writeFile(config.content);
|
|
71146
71465
|
} finally {
|
|
@@ -71169,7 +71488,7 @@ async function prepareChiefToolConfig(originalRepository, targetWorkspace) {
|
|
|
71169
71488
|
|
|
71170
71489
|
// src/tool-discovery.ts
|
|
71171
71490
|
init_client_toml();
|
|
71172
|
-
import { constants as
|
|
71491
|
+
import { constants as constants10 } from "node:fs";
|
|
71173
71492
|
import { access, lstat as lstat14, readFile as readFile12, realpath as realpath18 } from "node:fs/promises";
|
|
71174
71493
|
import { homedir as homedir6 } from "node:os";
|
|
71175
71494
|
import { delimiter as delimiter2, isAbsolute as isAbsolute11, join as join33, resolve as resolve18 } from "node:path";
|
|
@@ -71191,7 +71510,7 @@ async function executable(name, env) {
|
|
|
71191
71510
|
for (const directory of (env.PATH ?? "").split(delimiter2).filter(isAbsolute11)) {
|
|
71192
71511
|
try {
|
|
71193
71512
|
const path = join33(directory, name);
|
|
71194
|
-
await access(path,
|
|
71513
|
+
await access(path, constants10.X_OK);
|
|
71195
71514
|
if ((await lstat14(await realpath18(path))).isFile())
|
|
71196
71515
|
return true;
|
|
71197
71516
|
} catch {}
|
|
@@ -71446,7 +71765,7 @@ async function decideContinuousGoal(operation, decisionId, root, dependencies =
|
|
|
71446
71765
|
}
|
|
71447
71766
|
|
|
71448
71767
|
// src/chief-continuous.ts
|
|
71449
|
-
var execute = promisify2(
|
|
71768
|
+
var execute = promisify2(execFile5);
|
|
71450
71769
|
var orderKeys = [
|
|
71451
71770
|
"workspace",
|
|
71452
71771
|
"verify",
|
|
@@ -73135,7 +73454,7 @@ function selectTaskReviewer(mission, task, state) {
|
|
|
73135
73454
|
}
|
|
73136
73455
|
|
|
73137
73456
|
// ../../packages/core/src/chief/coordinator.ts
|
|
73138
|
-
var
|
|
73457
|
+
var bounded3 = (value) => value.slice(-32000);
|
|
73139
73458
|
async function coordinate(mission, ports) {
|
|
73140
73459
|
Object.assign(mission, validateMission(mission));
|
|
73141
73460
|
const operatorGoal = mission.goal;
|
|
@@ -73199,7 +73518,7 @@ async function coordinate(mission, ports) {
|
|
|
73199
73518
|
if (task.effectScope === "external" && state.effectState === "unknown")
|
|
73200
73519
|
throw new MissionPause(`External effect ${task.id} has no established destination outcome and will not be repeated.`, "unknown-effect");
|
|
73201
73520
|
if (task.effectScope !== "external" || state.effectState !== "completed") {
|
|
73202
|
-
state.output =
|
|
73521
|
+
state.output = bounded3(await run(persona(task.personaId), workPrompt(mission, task, state, persona(task.personaId)), "work", task.id));
|
|
73203
73522
|
if (task.effectScope === "external")
|
|
73204
73523
|
state.effectState = "completed";
|
|
73205
73524
|
}
|
|
@@ -73373,7 +73692,7 @@ async function coordinate(mission, ports) {
|
|
|
73373
73692
|
mission.fingerprint = await ports.fingerprint(mission);
|
|
73374
73693
|
mission.verification = {
|
|
73375
73694
|
ok: result.ok,
|
|
73376
|
-
output: result.output ?
|
|
73695
|
+
output: result.output ? bounded3(result.output) : undefined,
|
|
73377
73696
|
fingerprint: mission.fingerprint
|
|
73378
73697
|
};
|
|
73379
73698
|
if (mission.verificationMode === "chief" && !mission.goalVerification?.ok) {
|
|
@@ -73472,7 +73791,7 @@ async function coordinate(mission, ports) {
|
|
|
73472
73791
|
return mission;
|
|
73473
73792
|
}
|
|
73474
73793
|
mission.status = "failed";
|
|
73475
|
-
mission.error =
|
|
73794
|
+
mission.error = bounded3(error instanceof Error ? error.message : String(error));
|
|
73476
73795
|
if (error instanceof ReadOnlyViolation || error instanceof ContractViolation || error instanceof CheckpointError)
|
|
73477
73796
|
executionState(mission).failureKind = "integrity";
|
|
73478
73797
|
if (error instanceof ReadOnlyViolation)
|
|
@@ -73489,7 +73808,7 @@ async function coordinate(mission, ports) {
|
|
|
73489
73808
|
if (reportError instanceof ReadOnlyViolation) {
|
|
73490
73809
|
executionState(mission).failureKind = "integrity";
|
|
73491
73810
|
invalidate();
|
|
73492
|
-
mission.error =
|
|
73811
|
+
mission.error = bounded3(`${mission.error}
|
|
73493
73812
|
${reportError.message}`);
|
|
73494
73813
|
mission.report = fallbackReport(mission);
|
|
73495
73814
|
}
|
|
@@ -74623,6 +74942,37 @@ function checkOma(project, deps) {
|
|
|
74623
74942
|
return results;
|
|
74624
74943
|
}
|
|
74625
74944
|
|
|
74945
|
+
// src/doctor-skill-matrix-checks.ts
|
|
74946
|
+
import { resolve as resolve26 } from "node:path";
|
|
74947
|
+
async function checkSkillMatrix(project, global2, deps) {
|
|
74948
|
+
const config = project?.oma?.skill_compatibility;
|
|
74949
|
+
if (!config)
|
|
74950
|
+
return [];
|
|
74951
|
+
const projectActor = project?.actor ?? project?.agent;
|
|
74952
|
+
const globalActor = global2?.actor ?? global2?.agent;
|
|
74953
|
+
const actorType = projectActor?.type ?? globalActor?.type ?? "claude";
|
|
74954
|
+
const model = projectActor?.model ?? (globalActor?.type === actorType ? globalActor.model : undefined);
|
|
74955
|
+
const inspection = await inspectSkillCompatibility({
|
|
74956
|
+
reportPath: resolve26(deps.cwd, config.report_path),
|
|
74957
|
+
maxAgeHours: config.max_age_hours,
|
|
74958
|
+
mode: config.mode
|
|
74959
|
+
}, resolve26(deps.cwd, project?.workspace?.root ?? "."), undefined, [{ actorType, model }], deps.skillMatrix);
|
|
74960
|
+
const route = inspection.routes[0];
|
|
74961
|
+
const status = route?.status ?? "unknown";
|
|
74962
|
+
return [
|
|
74963
|
+
{
|
|
74964
|
+
id: "oma.skill-compatibility",
|
|
74965
|
+
name: "OMA skill read-reference compatibility",
|
|
74966
|
+
status,
|
|
74967
|
+
message: `${config.mode}: ${actorType}/${model ?? "native default"}: ${route?.reason ?? "Evidence unavailable."} Scope: ${inspection.scope}. Work dispatch rechecks its own selected skills and candidates.`,
|
|
74968
|
+
...status !== "pass" ? {
|
|
74969
|
+
fix: "Generate a completed installed injected matrix with explicit models and set oma.skill_compatibility.report_path in av.yaml. av doctor never runs a live matrix."
|
|
74970
|
+
} : {},
|
|
74971
|
+
critical: config.mode === "require"
|
|
74972
|
+
}
|
|
74973
|
+
];
|
|
74974
|
+
}
|
|
74975
|
+
|
|
74626
74976
|
// src/doctor-config-checks.ts
|
|
74627
74977
|
function checkTunnel(project, deps) {
|
|
74628
74978
|
const provider = project?.tunnel?.provider ?? "ngrok";
|
|
@@ -74877,10 +75227,11 @@ async function runDoctorChecks(deps, options = {}) {
|
|
|
74877
75227
|
results.push(checkTunnel(project, deps));
|
|
74878
75228
|
results.push(checkWebhookSecret(project));
|
|
74879
75229
|
results.push(...checkOma(project, deps));
|
|
75230
|
+
results.push(...await checkSkillMatrix(project, global2, deps));
|
|
74880
75231
|
return results;
|
|
74881
75232
|
}
|
|
74882
75233
|
function computeExitCode(results) {
|
|
74883
|
-
return results.some((r) => r.critical && r.status === "fail") ? 1 : 0;
|
|
75234
|
+
return results.some((r) => r.critical && (r.status === "fail" || r.status === "unknown")) ? 1 : 0;
|
|
74884
75235
|
}
|
|
74885
75236
|
function summarize(results) {
|
|
74886
75237
|
return { passed: results.filter((r) => r.status === "pass").length, total: results.length };
|
|
@@ -74955,7 +75306,7 @@ async function registerLinearWebhook(root, tunnelUrl) {
|
|
|
74955
75306
|
init_yaml_loader();
|
|
74956
75307
|
import { existsSync as existsSync5, readFileSync as readFileSync10, writeFileSync as writeFileSync2 } from "node:fs";
|
|
74957
75308
|
import { createServer as createServer3 } from "node:net";
|
|
74958
|
-
import { resolve as
|
|
75309
|
+
import { resolve as resolve27 } from "node:path";
|
|
74959
75310
|
import { setTimeout as delay } from "node:timers/promises";
|
|
74960
75311
|
|
|
74961
75312
|
// src/webhook-proxy.ts
|
|
@@ -75070,12 +75421,12 @@ function resolveServerPort(root, runningPort) {
|
|
|
75070
75421
|
return String(port);
|
|
75071
75422
|
}
|
|
75072
75423
|
function resolveRuntimePaths(root, cliDir) {
|
|
75073
|
-
const dashboardCwd =
|
|
75074
|
-
if (!existsSync5(
|
|
75424
|
+
const dashboardCwd = resolve27(root, "apps/dashboard");
|
|
75425
|
+
if (!existsSync5(resolve27(dashboardCwd, "package.json"))) {
|
|
75075
75426
|
throw new Error(`Dashboard source is missing at ${dashboardCwd}. Clone https://github.com/first-fluke/agent-valley, run bun install, then run bun av setup and bun av dev from that checkout. The standalone CLI does not include the dashboard.`);
|
|
75076
75427
|
}
|
|
75077
|
-
const bundled =
|
|
75078
|
-
const supervisorScript = existsSync5(bundled) ? bundled :
|
|
75428
|
+
const bundled = resolve27(cliDir, "supervisor.js");
|
|
75429
|
+
const supervisorScript = existsSync5(bundled) ? bundled : resolve27(cliDir, "supervisor.ts");
|
|
75079
75430
|
if (!existsSync5(supervisorScript)) {
|
|
75080
75431
|
throw new Error(`Supervisor is missing at ${supervisorScript}. Run bun av up from an intact Agent Valley checkout.`);
|
|
75081
75432
|
}
|
|
@@ -75354,8 +75705,8 @@ function spawnTunnel(config, input) {
|
|
|
75354
75705
|
|
|
75355
75706
|
// src/index.ts
|
|
75356
75707
|
var ROOT = process.cwd();
|
|
75357
|
-
var PID_FILE =
|
|
75358
|
-
var LOG_FILE =
|
|
75708
|
+
var PID_FILE = resolve31(ROOT, ".av.pid");
|
|
75709
|
+
var LOG_FILE = resolve31(ROOT, ".av.log");
|
|
75359
75710
|
function ensureConfig() {
|
|
75360
75711
|
if (!existsSync10(resolveProjectConfigPath(ROOT))) {
|
|
75361
75712
|
console.log(import_picocolors15.default.red("No av.yaml found. Run `av setup` first."));
|