@tangle-network/agent-eval 0.115.3 → 0.116.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/CHANGELOG.md +24 -0
- package/dist/analyst/index.d.ts +8 -10
- package/dist/analyst/index.js +27 -22
- package/dist/analyst/index.js.map +1 -1
- package/dist/{analyst-C8HHvfJp.d.ts → analyst-CFBc14Wc.d.ts} +1 -1
- package/dist/{analyze-runs-BYHg6Irm.d.ts → analyze-runs-0rz_m29H.d.ts} +3 -3
- package/dist/belief-state/index.d.ts +3 -3
- package/dist/benchmarks/index.d.ts +7 -3
- package/dist/benchmarks/index.js +4 -4
- package/dist/campaign/index.d.ts +212 -23
- package/dist/campaign/index.js +19 -4
- package/dist/{chunk-ADYLPOSX.js → chunk-3274WNK7.js} +427 -93
- package/dist/chunk-3274WNK7.js.map +1 -0
- package/dist/{chunk-I6LVHOV3.js → chunk-7GKEAIAD.js} +2 -2
- package/dist/{chunk-5S5NJ63F.js → chunk-CIUOICJT.js} +747 -2
- package/dist/chunk-CIUOICJT.js.map +1 -0
- package/dist/{chunk-KG4TD7EQ.js → chunk-GSW3OBHK.js} +1283 -181
- package/dist/chunk-GSW3OBHK.js.map +1 -0
- package/dist/chunk-MPHTT5HE.js +74 -0
- package/dist/chunk-MPHTT5HE.js.map +1 -0
- package/dist/{chunk-WSBUZMBU.js → chunk-NBSS5NDZ.js} +3 -3
- package/dist/{code-agent-session-D-g04tcy.d.ts → code-agent-session-CdxteG0y.d.ts} +1 -1
- package/dist/contract/index.d.ts +19 -19
- package/dist/contract/index.js +5 -3
- package/dist/contract/index.js.map +1 -1
- package/dist/{control-CcBiAEnn.d.ts → control-DbcDxouY.d.ts} +1 -1
- package/dist/control.d.ts +2 -2
- package/dist/{default-registry-DltpYR5u.d.ts → default-registry-DDfv22MQ.d.ts} +2 -1
- package/dist/{gepa-dne9JDPL.d.ts → gepa-CQelRtuC.d.ts} +10 -8
- package/dist/hosted/index.d.ts +8 -4
- package/dist/{index-BTEpx9He.d.ts → index-DbCXJfZ1.d.ts} +2 -2
- package/dist/index.d.ts +27 -30
- package/dist/index.js +26 -20
- package/dist/index.js.map +1 -1
- package/dist/{insight-report-IwwvqZZv.d.ts → insight-report-oMVxDTxl.d.ts} +1 -1
- package/dist/{integrity-qemeBAyx.d.ts → integrity-C6PZ73iC.d.ts} +1 -1
- package/dist/kind-factory-DWOvXjR_.d.ts +171 -0
- package/dist/meta-eval/index.d.ts +2 -2
- package/dist/multishot/index.d.ts +6 -2
- package/dist/openapi.json +1 -1
- package/dist/policy-edit-Clb2v6Oa.d.ts +708 -0
- package/dist/{pre-registration-D8h7ZxNL.d.ts → pre-registration--vU0mMtD.d.ts} +4 -4
- package/dist/{provenance-Bibyg1U9.d.ts → provenance-BbVagC68.d.ts} +26 -14
- package/dist/{release-report-CCtzajxP.d.ts → release-report-CamNDe90.d.ts} +2 -2
- package/dist/reporting.d.ts +4 -4
- package/dist/{researcher-Dq-EtpbE.d.ts → researcher-Dwbo_Fxx.d.ts} +5 -5
- package/dist/rl.d.ts +11 -9
- package/dist/{rubric-predictive-validity-DYTLjGWu.d.ts → rubric-predictive-validity-BIdf9h4R.d.ts} +1 -1
- package/dist/{run-record-B7RTi_ix.d.ts → run-record-CZmcpWPo.d.ts} +1 -1
- package/dist/{runtime-trajectory-Dws7Kpgi.d.ts → runtime-trajectory-CC0jx9ql.d.ts} +1 -1
- package/dist/{semantic-concept-judge-DxJmRkyJ.d.ts → semantic-concept-judge-CKjePUMh.d.ts} +3 -3
- package/dist/{store-C1YxJDEK.d.ts → store-9cAScOcb.d.ts} +132 -1
- package/dist/{summary-report-BJ5aNwZ1.d.ts → summary-report-DTNgQycC.d.ts} +1 -1
- package/dist/traces.d.ts +6 -8
- package/dist/{types-C5gJrOVT.d.ts → types-Ca_63YSD.d.ts} +59 -2
- package/docs/design/loop-taxonomy.md +1 -2
- package/package.json +1 -1
- package/dist/chunk-5S5NJ63F.js.map +0 -1
- package/dist/chunk-ADYLPOSX.js.map +0 -1
- package/dist/chunk-KG4TD7EQ.js.map +0 -1
- package/dist/chunk-QMXXSNC4.js +0 -761
- package/dist/chunk-QMXXSNC4.js.map +0 -1
- package/dist/kind-factory-DcNg13sZ.d.ts +0 -508
- package/dist/llm-client-DyqEH4jH.d.ts +0 -265
- package/dist/policy-edit-RLn8GWof.d.ts +0 -103
- package/dist/raw-provider-sink-C46HDghv.d.ts +0 -132
- /package/dist/{chunk-I6LVHOV3.js.map → chunk-7GKEAIAD.js.map} +0 -0
- /package/dist/{chunk-WSBUZMBU.js.map → chunk-NBSS5NDZ.js.map} +0 -0
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
runImprovementLoop,
|
|
13
13
|
surfaceContentHash,
|
|
14
14
|
surfaceHash
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-3274WNK7.js";
|
|
16
16
|
import {
|
|
17
17
|
estimateCost,
|
|
18
18
|
isModelPriced
|
|
@@ -26,17 +26,23 @@ import {
|
|
|
26
26
|
} from "./chunk-FAOEFFRT.js";
|
|
27
27
|
import {
|
|
28
28
|
Mutex,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
clamp01,
|
|
32
|
-
isPolicyEdit,
|
|
33
|
-
policyEditsFromFindings
|
|
34
|
-
} from "./chunk-QMXXSNC4.js";
|
|
29
|
+
clamp01
|
|
30
|
+
} from "./chunk-MPHTT5HE.js";
|
|
35
31
|
import {
|
|
36
32
|
AnalystRegistry,
|
|
37
33
|
DEFAULT_TRACE_ANALYST_KINDS,
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
POLICY_EDIT_AXES,
|
|
35
|
+
POLICY_EDIT_TARGET_SURFACES,
|
|
36
|
+
admitPolicyEdit,
|
|
37
|
+
applyPolicyEditToSurface,
|
|
38
|
+
assertNoJudgeVerdict,
|
|
39
|
+
createTraceAnalystKind,
|
|
40
|
+
isPolicyEdit,
|
|
41
|
+
makePolicyEdit,
|
|
42
|
+
makePolicyEditCandidateRecord,
|
|
43
|
+
policyEditsFromFindings,
|
|
44
|
+
validatePolicyEditCandidateRecord
|
|
45
|
+
} from "./chunk-CIUOICJT.js";
|
|
40
46
|
import {
|
|
41
47
|
eProcess,
|
|
42
48
|
mcnemar,
|
|
@@ -63,7 +69,8 @@ import {
|
|
|
63
69
|
canonicalize
|
|
64
70
|
} from "./chunk-VSMTAMNK.js";
|
|
65
71
|
import {
|
|
66
|
-
callLlm
|
|
72
|
+
callLlm,
|
|
73
|
+
callLlmJson
|
|
67
74
|
} from "./chunk-GY4SYVPJ.js";
|
|
68
75
|
import {
|
|
69
76
|
AgentEvalError,
|
|
@@ -5130,10 +5137,16 @@ function compositeProposer(opts) {
|
|
|
5130
5137
|
const surface = isCandidate ? proposal.surface : proposal;
|
|
5131
5138
|
const label = isCandidate ? proposal.label : "candidate";
|
|
5132
5139
|
const rationale = isCandidate ? proposal.rationale : "";
|
|
5140
|
+
const candidateRecord = isCandidate ? proposal.candidateRecord : void 0;
|
|
5133
5141
|
const key = surfaceContentHash(surface);
|
|
5134
5142
|
if (seen.has(key)) continue;
|
|
5135
5143
|
seen.add(key);
|
|
5136
|
-
pool.push({
|
|
5144
|
+
pool.push({
|
|
5145
|
+
surface,
|
|
5146
|
+
label: `${member.kind}:${label}`,
|
|
5147
|
+
rationale,
|
|
5148
|
+
...candidateRecord ? { candidateRecord } : {}
|
|
5149
|
+
});
|
|
5137
5150
|
}
|
|
5138
5151
|
} catch (err) {
|
|
5139
5152
|
errors.push(`${member.kind}: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -5264,6 +5277,1153 @@ ${findings.slice(0, 800)}`,
|
|
|
5264
5277
|
});
|
|
5265
5278
|
}
|
|
5266
5279
|
|
|
5280
|
+
// src/campaign/proposers/llm-policy-edit.ts
|
|
5281
|
+
import { z } from "zod";
|
|
5282
|
+
|
|
5283
|
+
// src/campaign/proposers/policy-edit.ts
|
|
5284
|
+
function policyEditProposer(opts = {}) {
|
|
5285
|
+
return {
|
|
5286
|
+
kind: "policy-edit",
|
|
5287
|
+
async propose(ctx) {
|
|
5288
|
+
const edits = materializePolicyEdits(opts.edits ?? ctx.findings, opts.findingOptions);
|
|
5289
|
+
const limit = Math.max(
|
|
5290
|
+
0,
|
|
5291
|
+
Math.min(opts.maxCandidates ?? ctx.populationSize, ctx.populationSize)
|
|
5292
|
+
);
|
|
5293
|
+
const out = [];
|
|
5294
|
+
const seen = /* @__PURE__ */ new Set([surfaceContentHash(ctx.currentSurface)]);
|
|
5295
|
+
if (limit === 0) return out;
|
|
5296
|
+
for (const edit of edits) {
|
|
5297
|
+
const admission = admitPolicyEdit(edit, opts.admission);
|
|
5298
|
+
opts.onAdmission?.(admission);
|
|
5299
|
+
if (admission.decision !== "admit") continue;
|
|
5300
|
+
const surface = coerceCandidateSurface(applyPolicyEditToSurface(ctx.currentSurface, edit));
|
|
5301
|
+
const hash = surfaceContentHash(surface);
|
|
5302
|
+
if (seen.has(hash)) continue;
|
|
5303
|
+
seen.add(hash);
|
|
5304
|
+
out.push({
|
|
5305
|
+
surface,
|
|
5306
|
+
label: `policy-edit:${edit.axis}`,
|
|
5307
|
+
rationale: `${edit.editId} expected ${edit.expectedGain.direction} ${edit.expectedGain.metric} by ${edit.expectedGain.amount}; source findings [${edit.source.findingIds.join(", ")}]`,
|
|
5308
|
+
candidateRecord: makePolicyEditCandidateRecord(edit)
|
|
5309
|
+
});
|
|
5310
|
+
if (out.length >= limit) break;
|
|
5311
|
+
}
|
|
5312
|
+
return out;
|
|
5313
|
+
}
|
|
5314
|
+
};
|
|
5315
|
+
}
|
|
5316
|
+
function materializePolicyEdits(inputs, findingOptions) {
|
|
5317
|
+
const edits = [];
|
|
5318
|
+
const findings = [];
|
|
5319
|
+
for (const input of inputs) {
|
|
5320
|
+
if (isPolicyEdit(input)) {
|
|
5321
|
+
edits.push(input);
|
|
5322
|
+
} else if (isAnalystFindingLike(input)) {
|
|
5323
|
+
findings.push(input);
|
|
5324
|
+
}
|
|
5325
|
+
}
|
|
5326
|
+
if (findings.length > 0) edits.push(...policyEditsFromFindings(findings, findingOptions));
|
|
5327
|
+
return edits;
|
|
5328
|
+
}
|
|
5329
|
+
function isAnalystFindingLike(input) {
|
|
5330
|
+
if (!input || typeof input !== "object") return false;
|
|
5331
|
+
const obj = input;
|
|
5332
|
+
return typeof obj.finding_id === "string" && typeof obj.analyst_id === "string" && typeof obj.claim === "string" && Array.isArray(obj.evidence_refs);
|
|
5333
|
+
}
|
|
5334
|
+
function coerceCandidateSurface(surface) {
|
|
5335
|
+
if (typeof surface === "string") return surface;
|
|
5336
|
+
if (surface && typeof surface === "object") {
|
|
5337
|
+
const obj = surface;
|
|
5338
|
+
if (obj.kind === "code" && typeof obj.worktreeRef === "string") {
|
|
5339
|
+
assertCodeSurfaceIdentity(surface);
|
|
5340
|
+
return surface;
|
|
5341
|
+
}
|
|
5342
|
+
return JSON.stringify(surface, null, 2);
|
|
5343
|
+
}
|
|
5344
|
+
throw new Error("policyEditProposer: policy edit produced an unsupported surface");
|
|
5345
|
+
}
|
|
5346
|
+
|
|
5347
|
+
// src/campaign/proposers/policy-edit-author-context.ts
|
|
5348
|
+
function selectPolicyEditAuthorRows(rows, options) {
|
|
5349
|
+
assertPositiveSafeInteger(options.limit, "limit");
|
|
5350
|
+
const unique2 = /* @__PURE__ */ new Map();
|
|
5351
|
+
for (const row of rows) {
|
|
5352
|
+
if (!row.scenarioId || row.scenarioId.trim() !== row.scenarioId) {
|
|
5353
|
+
throw new Error("selectPolicyEditAuthorRows: scenarioId must be trimmed and non-empty");
|
|
5354
|
+
}
|
|
5355
|
+
if (!Number.isFinite(row.composite)) {
|
|
5356
|
+
throw new Error(
|
|
5357
|
+
`selectPolicyEditAuthorRows: composite must be finite for '${row.scenarioId}'`
|
|
5358
|
+
);
|
|
5359
|
+
}
|
|
5360
|
+
if (unique2.has(row.scenarioId)) continue;
|
|
5361
|
+
const reference = options.referenceByScenario?.get(row.scenarioId);
|
|
5362
|
+
if (reference !== void 0 && !Number.isFinite(reference)) {
|
|
5363
|
+
throw new Error(
|
|
5364
|
+
`selectPolicyEditAuthorRows: reference must be finite for '${row.scenarioId}'`
|
|
5365
|
+
);
|
|
5366
|
+
}
|
|
5367
|
+
unique2.set(row.scenarioId, {
|
|
5368
|
+
row,
|
|
5369
|
+
delta: reference === void 0 ? null : row.composite - reference
|
|
5370
|
+
});
|
|
5371
|
+
}
|
|
5372
|
+
const hardest = [...unique2.values()].sort(
|
|
5373
|
+
(a, b) => a.row.composite - b.row.composite || compareScenarioId(a.row, b.row)
|
|
5374
|
+
);
|
|
5375
|
+
const regressions = [...unique2.values()].filter((entry) => entry.delta !== null && entry.delta < 0).sort((a, b) => a.delta - b.delta || compareScenarioId(a.row, b.row));
|
|
5376
|
+
const improvements = [...unique2.values()].filter((entry) => entry.delta !== null && entry.delta > 0).sort((a, b) => b.delta - a.delta || compareScenarioId(a.row, b.row));
|
|
5377
|
+
const rankings = [hardest, regressions, improvements];
|
|
5378
|
+
const maxDepth = Math.max(...rankings.map((ranking) => ranking.length), 0);
|
|
5379
|
+
const selected = [];
|
|
5380
|
+
const selectedIds = /* @__PURE__ */ new Set();
|
|
5381
|
+
for (let depth = 0; depth < maxDepth && selected.length < options.limit; depth += 1) {
|
|
5382
|
+
for (const ranking of rankings) {
|
|
5383
|
+
const entry = ranking[depth];
|
|
5384
|
+
if (!entry || selectedIds.has(entry.row.scenarioId)) continue;
|
|
5385
|
+
selected.push(entry.row);
|
|
5386
|
+
selectedIds.add(entry.row.scenarioId);
|
|
5387
|
+
if (selected.length === options.limit) break;
|
|
5388
|
+
}
|
|
5389
|
+
}
|
|
5390
|
+
return selected;
|
|
5391
|
+
}
|
|
5392
|
+
function assertPolicyEditAuthorContextBudget(value, maxChars) {
|
|
5393
|
+
assertPositiveSafeInteger(maxChars, "maxChars");
|
|
5394
|
+
const json = JSON.stringify(value);
|
|
5395
|
+
if (json === void 0) {
|
|
5396
|
+
throw new Error("assertPolicyEditAuthorContextBudget: value must serialize to JSON");
|
|
5397
|
+
}
|
|
5398
|
+
const actualChars = json.length;
|
|
5399
|
+
if (actualChars > maxChars) {
|
|
5400
|
+
throw new Error(
|
|
5401
|
+
`assertPolicyEditAuthorContextBudget: serialized JSON exceeds budget (actualChars=${actualChars}, maxChars=${maxChars})`
|
|
5402
|
+
);
|
|
5403
|
+
}
|
|
5404
|
+
return { json, actualChars, maxChars };
|
|
5405
|
+
}
|
|
5406
|
+
function compareScenarioId(a, b) {
|
|
5407
|
+
return a.scenarioId < b.scenarioId ? -1 : a.scenarioId > b.scenarioId ? 1 : 0;
|
|
5408
|
+
}
|
|
5409
|
+
function assertPositiveSafeInteger(value, name) {
|
|
5410
|
+
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
5411
|
+
throw new Error(`${name} must be a positive safe integer (got ${value})`);
|
|
5412
|
+
}
|
|
5413
|
+
}
|
|
5414
|
+
|
|
5415
|
+
// src/campaign/proposers/llm-policy-edit.ts
|
|
5416
|
+
var JSON_POLICY_EDIT_TARGET_SURFACES = [
|
|
5417
|
+
"prompt",
|
|
5418
|
+
"tool-contract",
|
|
5419
|
+
"runtime-config",
|
|
5420
|
+
"memory",
|
|
5421
|
+
"agent-profile"
|
|
5422
|
+
];
|
|
5423
|
+
var NonEmptyStringSchema = z.string().trim().min(1);
|
|
5424
|
+
var JsonValueSchema = z.lazy(
|
|
5425
|
+
() => z.union([
|
|
5426
|
+
z.string(),
|
|
5427
|
+
z.number().finite(),
|
|
5428
|
+
z.boolean(),
|
|
5429
|
+
z.null(),
|
|
5430
|
+
z.array(JsonValueSchema),
|
|
5431
|
+
z.record(NonEmptyStringSchema, JsonValueSchema)
|
|
5432
|
+
])
|
|
5433
|
+
);
|
|
5434
|
+
var AuthoredJsonChangeSchema = z.discriminatedUnion("mode", [
|
|
5435
|
+
z.object({
|
|
5436
|
+
kind: z.literal("json"),
|
|
5437
|
+
mode: z.literal("set"),
|
|
5438
|
+
path: NonEmptyStringSchema,
|
|
5439
|
+
value: JsonValueSchema
|
|
5440
|
+
}).strict(),
|
|
5441
|
+
z.object({
|
|
5442
|
+
kind: z.literal("json"),
|
|
5443
|
+
mode: z.literal("merge"),
|
|
5444
|
+
path: NonEmptyStringSchema,
|
|
5445
|
+
value: JsonValueSchema
|
|
5446
|
+
}).strict(),
|
|
5447
|
+
z.object({
|
|
5448
|
+
kind: z.literal("json"),
|
|
5449
|
+
mode: z.literal("remove"),
|
|
5450
|
+
path: NonEmptyStringSchema
|
|
5451
|
+
}).strict()
|
|
5452
|
+
]);
|
|
5453
|
+
var AuthoredPolicyEditSchema = z.object({
|
|
5454
|
+
axis: z.enum(POLICY_EDIT_AXES),
|
|
5455
|
+
target: z.object({
|
|
5456
|
+
surface: z.enum(POLICY_EDIT_TARGET_SURFACES),
|
|
5457
|
+
path: NonEmptyStringSchema,
|
|
5458
|
+
label: NonEmptyStringSchema.max(200).nullable()
|
|
5459
|
+
}).strict(),
|
|
5460
|
+
change: AuthoredJsonChangeSchema,
|
|
5461
|
+
claim: NonEmptyStringSchema.max(2e3),
|
|
5462
|
+
expectedGain: z.object({
|
|
5463
|
+
metric: NonEmptyStringSchema.max(400),
|
|
5464
|
+
direction: z.enum(["increase", "decrease"]),
|
|
5465
|
+
amount: z.number().finite().positive(),
|
|
5466
|
+
unit: z.enum(["absolute", "relative", "percent", "score"]).nullable(),
|
|
5467
|
+
rationale: NonEmptyStringSchema.max(2e3).nullable()
|
|
5468
|
+
}).strict(),
|
|
5469
|
+
confidence: z.number().finite().min(0).max(1),
|
|
5470
|
+
risk: z.enum(["low", "medium", "high", "unknown"]),
|
|
5471
|
+
source: z.object({
|
|
5472
|
+
findingKeys: z.array(NonEmptyStringSchema).min(1).refine((ids) => new Set(ids).size === ids.length, "findingKeys must be unique")
|
|
5473
|
+
}).strict(),
|
|
5474
|
+
rationale: NonEmptyStringSchema.max(4e3).nullable(),
|
|
5475
|
+
validationPlan: NonEmptyStringSchema.max(2e3).nullable()
|
|
5476
|
+
}).strict();
|
|
5477
|
+
var PolicyEditAuthorResponseSchema = z.object({
|
|
5478
|
+
edits: z.array(AuthoredPolicyEditSchema)
|
|
5479
|
+
}).strict();
|
|
5480
|
+
var POLICY_EDIT_AUTHOR_JSON_SCHEMA = {
|
|
5481
|
+
type: "object",
|
|
5482
|
+
additionalProperties: false,
|
|
5483
|
+
required: ["edits"],
|
|
5484
|
+
properties: {
|
|
5485
|
+
edits: {
|
|
5486
|
+
type: "array",
|
|
5487
|
+
items: {
|
|
5488
|
+
type: "object",
|
|
5489
|
+
additionalProperties: false,
|
|
5490
|
+
required: [
|
|
5491
|
+
"axis",
|
|
5492
|
+
"target",
|
|
5493
|
+
"change",
|
|
5494
|
+
"claim",
|
|
5495
|
+
"expectedGain",
|
|
5496
|
+
"confidence",
|
|
5497
|
+
"risk",
|
|
5498
|
+
"source",
|
|
5499
|
+
"rationale",
|
|
5500
|
+
"validationPlan"
|
|
5501
|
+
],
|
|
5502
|
+
properties: {
|
|
5503
|
+
axis: { type: "string", enum: [...POLICY_EDIT_AXES] },
|
|
5504
|
+
target: {
|
|
5505
|
+
type: "object",
|
|
5506
|
+
additionalProperties: false,
|
|
5507
|
+
required: ["surface", "path", "label"],
|
|
5508
|
+
properties: {
|
|
5509
|
+
surface: { type: "string", enum: [...POLICY_EDIT_TARGET_SURFACES] },
|
|
5510
|
+
path: { type: "string", minLength: 1 },
|
|
5511
|
+
label: { type: ["string", "null"], maxLength: 200 }
|
|
5512
|
+
}
|
|
5513
|
+
},
|
|
5514
|
+
change: {
|
|
5515
|
+
anyOf: [
|
|
5516
|
+
{
|
|
5517
|
+
type: "object",
|
|
5518
|
+
additionalProperties: false,
|
|
5519
|
+
required: ["kind", "mode", "path", "value"],
|
|
5520
|
+
properties: {
|
|
5521
|
+
kind: { const: "json" },
|
|
5522
|
+
mode: { const: "set" },
|
|
5523
|
+
path: { type: "string", minLength: 1 },
|
|
5524
|
+
value: {}
|
|
5525
|
+
}
|
|
5526
|
+
},
|
|
5527
|
+
{
|
|
5528
|
+
type: "object",
|
|
5529
|
+
additionalProperties: false,
|
|
5530
|
+
required: ["kind", "mode", "path", "value"],
|
|
5531
|
+
properties: {
|
|
5532
|
+
kind: { const: "json" },
|
|
5533
|
+
mode: { const: "merge" },
|
|
5534
|
+
path: { type: "string", minLength: 1 },
|
|
5535
|
+
value: {}
|
|
5536
|
+
}
|
|
5537
|
+
},
|
|
5538
|
+
{
|
|
5539
|
+
type: "object",
|
|
5540
|
+
additionalProperties: false,
|
|
5541
|
+
required: ["kind", "mode", "path"],
|
|
5542
|
+
properties: {
|
|
5543
|
+
kind: { const: "json" },
|
|
5544
|
+
mode: { const: "remove" },
|
|
5545
|
+
path: { type: "string", minLength: 1 }
|
|
5546
|
+
}
|
|
5547
|
+
}
|
|
5548
|
+
]
|
|
5549
|
+
},
|
|
5550
|
+
claim: { type: "string", minLength: 1, maxLength: 2e3 },
|
|
5551
|
+
expectedGain: {
|
|
5552
|
+
type: "object",
|
|
5553
|
+
additionalProperties: false,
|
|
5554
|
+
required: ["metric", "direction", "amount", "unit", "rationale"],
|
|
5555
|
+
properties: {
|
|
5556
|
+
metric: { type: "string", minLength: 1, maxLength: 400 },
|
|
5557
|
+
direction: { type: "string", enum: ["increase", "decrease"] },
|
|
5558
|
+
amount: { type: "number", exclusiveMinimum: 0 },
|
|
5559
|
+
unit: {
|
|
5560
|
+
type: ["string", "null"],
|
|
5561
|
+
enum: ["absolute", "relative", "percent", "score", null]
|
|
5562
|
+
},
|
|
5563
|
+
rationale: { type: ["string", "null"], maxLength: 2e3 }
|
|
5564
|
+
}
|
|
5565
|
+
},
|
|
5566
|
+
confidence: { type: "number", minimum: 0, maximum: 1 },
|
|
5567
|
+
risk: { type: "string", enum: ["low", "medium", "high", "unknown"] },
|
|
5568
|
+
source: {
|
|
5569
|
+
type: "object",
|
|
5570
|
+
additionalProperties: false,
|
|
5571
|
+
required: ["findingKeys"],
|
|
5572
|
+
properties: {
|
|
5573
|
+
findingKeys: {
|
|
5574
|
+
type: "array",
|
|
5575
|
+
minItems: 1,
|
|
5576
|
+
uniqueItems: true,
|
|
5577
|
+
items: { type: "string", minLength: 1 }
|
|
5578
|
+
}
|
|
5579
|
+
}
|
|
5580
|
+
},
|
|
5581
|
+
rationale: { type: ["string", "null"], maxLength: 4e3 },
|
|
5582
|
+
validationPlan: { type: ["string", "null"], maxLength: 2e3 }
|
|
5583
|
+
}
|
|
5584
|
+
}
|
|
5585
|
+
}
|
|
5586
|
+
}
|
|
5587
|
+
};
|
|
5588
|
+
function policyEditAuthorJsonSchema(maxItems, targetSurface, allowedJsonPaths, objectives) {
|
|
5589
|
+
const schema = JSON.parse(JSON.stringify(POLICY_EDIT_AUTHOR_JSON_SCHEMA));
|
|
5590
|
+
const properties = schema.properties;
|
|
5591
|
+
const edits = properties.edits;
|
|
5592
|
+
edits.maxItems = maxItems;
|
|
5593
|
+
const item = edits.items;
|
|
5594
|
+
const itemProperties = item.properties;
|
|
5595
|
+
const target = itemProperties.target;
|
|
5596
|
+
const targetProperties = target.properties;
|
|
5597
|
+
targetProperties.surface = { type: "string", enum: [targetSurface] };
|
|
5598
|
+
targetProperties.path = { type: "string", enum: [...allowedJsonPaths] };
|
|
5599
|
+
const change = itemProperties.change;
|
|
5600
|
+
for (const variant of change.anyOf) {
|
|
5601
|
+
const variantProperties = variant.properties;
|
|
5602
|
+
variantProperties.path = { type: "string", enum: [...allowedJsonPaths] };
|
|
5603
|
+
}
|
|
5604
|
+
const expectedGain = itemProperties.expectedGain;
|
|
5605
|
+
const gainProperties = expectedGain.properties;
|
|
5606
|
+
gainProperties.metric = { type: "string", enum: objectives.map((objective) => objective.key) };
|
|
5607
|
+
gainProperties.direction = {
|
|
5608
|
+
type: "string",
|
|
5609
|
+
enum: [...new Set(objectives.map((objective) => objective.direction))]
|
|
5610
|
+
};
|
|
5611
|
+
gainProperties.unit = {
|
|
5612
|
+
type: "string",
|
|
5613
|
+
enum: [...new Set(objectives.map((objective) => objective.unit))]
|
|
5614
|
+
};
|
|
5615
|
+
return schema;
|
|
5616
|
+
}
|
|
5617
|
+
var DEFAULT_POLICY_EDIT_HISTORY_LIMITS = Object.freeze({
|
|
5618
|
+
generations: 4,
|
|
5619
|
+
candidatesPerGeneration: 16,
|
|
5620
|
+
scenariosPerCandidate: 12,
|
|
5621
|
+
findings: 32,
|
|
5622
|
+
authorContextChars: 2e5
|
|
5623
|
+
});
|
|
5624
|
+
var POLICY_EDIT_AUTHOR_SYSTEM = [
|
|
5625
|
+
"You author strictly typed PolicyEdit candidates over one JSON surface.",
|
|
5626
|
+
'Return exactly one JSON object with shape {"edits":[...]}; emit an empty edits array when no evidence supports a change.',
|
|
5627
|
+
`axis must be one of: ${POLICY_EDIT_AXES.join(", ")}.`,
|
|
5628
|
+
`target.surface must be one of: ${POLICY_EDIT_TARGET_SURFACES.join(", ")}.`,
|
|
5629
|
+
"target.path and change.path must be the same caller-allowed JSON path.",
|
|
5630
|
+
'change must be exactly one operation: {"kind":"json","mode":"set","path":string,"value":json}, {"kind":"json","mode":"merge","path":string,"value":json}, or {"kind":"json","mode":"remove","path":string}.',
|
|
5631
|
+
"Nullable fields required by the response schema must be null when they do not apply.",
|
|
5632
|
+
"Every edit must cite one or more supplied finding keys in source.findingKeys. Do not emit persistent finding IDs, analyst IDs, or evidence references; the caller binds those from the cited findings.",
|
|
5633
|
+
"Treat expectedGain and confidence as forecasts, never as measured evidence. Learn from baselineOutcome, incumbentOutcome, and observedDeltaFromParent.",
|
|
5634
|
+
"Do not invent a finding, path, field, score, or task fact. Do not include schemaVersion, editId, metadata, prose, or undeclared keys."
|
|
5635
|
+
].join("\n");
|
|
5636
|
+
function llmPolicyEditProposer(opts) {
|
|
5637
|
+
const allowedJsonPaths = validateAllowedJsonPaths(opts.allowedJsonPaths);
|
|
5638
|
+
const allowedPathSet = new Set(allowedJsonPaths);
|
|
5639
|
+
const objectives = validateObjectives(opts.objectives);
|
|
5640
|
+
const objectiveByKey = new Map(objectives.map((objective) => [objective.key, objective]));
|
|
5641
|
+
requireNonEmpty(opts.model, "model");
|
|
5642
|
+
requireNonEmpty(opts.target, "target");
|
|
5643
|
+
if (!JSON_POLICY_EDIT_TARGET_SURFACES.includes(opts.targetSurface)) {
|
|
5644
|
+
throw new Error(
|
|
5645
|
+
`llmPolicyEditProposer: targetSurface '${opts.targetSurface}' is not a JSON-backed surface`
|
|
5646
|
+
);
|
|
5647
|
+
}
|
|
5648
|
+
if (opts.maxCandidates !== void 0 && (!Number.isSafeInteger(opts.maxCandidates) || opts.maxCandidates < 0)) {
|
|
5649
|
+
throw new Error("llmPolicyEditProposer: maxCandidates must be a non-negative safe integer");
|
|
5650
|
+
}
|
|
5651
|
+
const admissionMode = opts.admissionMode ?? "evidence-only";
|
|
5652
|
+
if (admissionMode !== "evidence-only" && admissionMode !== "strict") {
|
|
5653
|
+
throw new Error("llmPolicyEditProposer: admissionMode must be 'evidence-only' or 'strict'");
|
|
5654
|
+
}
|
|
5655
|
+
if (opts.admission && admissionMode !== "strict") {
|
|
5656
|
+
throw new Error("llmPolicyEditProposer: admission thresholds require admissionMode: 'strict'");
|
|
5657
|
+
}
|
|
5658
|
+
const historyLimits = validateHistoryLimits({
|
|
5659
|
+
...opts.maxHistoryGenerations === void 0 ? {} : { maxGenerations: opts.maxHistoryGenerations },
|
|
5660
|
+
...opts.maxHistoryCandidatesPerGeneration === void 0 ? {} : { maxCandidatesPerGeneration: opts.maxHistoryCandidatesPerGeneration },
|
|
5661
|
+
...opts.maxScenariosPerCandidate === void 0 ? {} : { maxScenariosPerCandidate: opts.maxScenariosPerCandidate },
|
|
5662
|
+
...opts.scenarioIdTransform === void 0 ? {} : { scenarioIdTransform: opts.scenarioIdTransform }
|
|
5663
|
+
});
|
|
5664
|
+
const maxFindings = positiveLimit(
|
|
5665
|
+
opts.maxFindings ?? DEFAULT_POLICY_EDIT_HISTORY_LIMITS.findings,
|
|
5666
|
+
"maxFindings"
|
|
5667
|
+
);
|
|
5668
|
+
const maxAuthorContextChars = positiveLimit(
|
|
5669
|
+
opts.maxAuthorContextChars ?? DEFAULT_POLICY_EDIT_HISTORY_LIMITS.authorContextChars,
|
|
5670
|
+
"maxAuthorContextChars"
|
|
5671
|
+
);
|
|
5672
|
+
return {
|
|
5673
|
+
kind: "llm-policy-edit",
|
|
5674
|
+
async propose(ctx) {
|
|
5675
|
+
const limit = Math.min(ctx.populationSize, opts.maxCandidates ?? ctx.populationSize);
|
|
5676
|
+
if (limit <= 0) return [];
|
|
5677
|
+
const currentSurface = parseJsonSurface(ctx.currentSurface);
|
|
5678
|
+
assertSearchOutcome(ctx.baselineOutcome, "baselineOutcome");
|
|
5679
|
+
assertSearchOutcome(ctx.incumbentOutcome, "incumbentOutcome");
|
|
5680
|
+
assertMeasuredCompositesInScale(ctx, objectives[0]);
|
|
5681
|
+
const scenarioIds = createScenarioIdProjector(historyLimits.scenarioIdTransform);
|
|
5682
|
+
registerOutcomeScenarioIds(ctx.baselineOutcome, scenarioIds);
|
|
5683
|
+
registerOutcomeScenarioIds(ctx.incumbentOutcome, scenarioIds);
|
|
5684
|
+
registerHistoryScenarioIds(ctx.history.slice(-historyLimits.maxGenerations), scenarioIds);
|
|
5685
|
+
assertSurfaceIsTaskAgnostic(
|
|
5686
|
+
{ currentSurface, allowedJsonPaths, objectives, targetSurface: opts.targetSurface },
|
|
5687
|
+
scenarioIds
|
|
5688
|
+
);
|
|
5689
|
+
const measuredSources = measuredSourceMeasurements(ctx);
|
|
5690
|
+
const findings = citableFindings(ctx.findings, measuredSources, maxFindings);
|
|
5691
|
+
const findingByKey = new Map(
|
|
5692
|
+
findings.map((finding, index) => [`finding-${index + 1}`, finding])
|
|
5693
|
+
);
|
|
5694
|
+
const authorContext = {
|
|
5695
|
+
target: scenarioIds.sanitize(opts.target),
|
|
5696
|
+
targetSurface: opts.targetSurface,
|
|
5697
|
+
allowedJsonPaths,
|
|
5698
|
+
objectives,
|
|
5699
|
+
candidateCount: limit,
|
|
5700
|
+
generation: ctx.generation,
|
|
5701
|
+
currentSurface,
|
|
5702
|
+
findings: findings.map(
|
|
5703
|
+
(finding, index) => renderFinding(finding, `finding-${index + 1}`, scenarioIds, measuredSources)
|
|
5704
|
+
),
|
|
5705
|
+
baselineOutcome: projectOutcome(
|
|
5706
|
+
ctx.baselineOutcome,
|
|
5707
|
+
scenarioIds,
|
|
5708
|
+
historyLimits.maxScenariosPerCandidate
|
|
5709
|
+
),
|
|
5710
|
+
incumbentOutcome: projectOutcome(
|
|
5711
|
+
ctx.incumbentOutcome,
|
|
5712
|
+
scenarioIds,
|
|
5713
|
+
historyLimits.maxScenariosPerCandidate,
|
|
5714
|
+
ctx.baselineOutcome
|
|
5715
|
+
),
|
|
5716
|
+
history: projectPolicyEditHistoryWithProjector(
|
|
5717
|
+
ctx.history,
|
|
5718
|
+
historyLimits,
|
|
5719
|
+
scenarioIds,
|
|
5720
|
+
objectiveByKey
|
|
5721
|
+
)
|
|
5722
|
+
};
|
|
5723
|
+
const responseSchema = policyEditAuthorJsonSchema(
|
|
5724
|
+
limit,
|
|
5725
|
+
opts.targetSurface,
|
|
5726
|
+
allowedJsonPaths,
|
|
5727
|
+
objectives
|
|
5728
|
+
);
|
|
5729
|
+
assertPolicyEditAuthorContextBudget(
|
|
5730
|
+
{ system: POLICY_EDIT_AUTHOR_SYSTEM, authorContext, responseSchema },
|
|
5731
|
+
maxAuthorContextChars
|
|
5732
|
+
);
|
|
5733
|
+
const userContent = JSON.stringify(authorContext);
|
|
5734
|
+
const { value } = await callLlmJson(
|
|
5735
|
+
{
|
|
5736
|
+
model: opts.model,
|
|
5737
|
+
messages: [
|
|
5738
|
+
{ role: "system", content: POLICY_EDIT_AUTHOR_SYSTEM },
|
|
5739
|
+
{
|
|
5740
|
+
role: "user",
|
|
5741
|
+
content: userContent
|
|
5742
|
+
}
|
|
5743
|
+
],
|
|
5744
|
+
jsonSchema: {
|
|
5745
|
+
name: "policy_edit_author",
|
|
5746
|
+
schema: responseSchema
|
|
5747
|
+
},
|
|
5748
|
+
temperature: opts.temperature ?? 0.2,
|
|
5749
|
+
maxTokens: opts.maxTokens ?? 6e3,
|
|
5750
|
+
timeoutMs: opts.timeoutMs
|
|
5751
|
+
},
|
|
5752
|
+
{ ...opts.llm, signal: ctx.signal }
|
|
5753
|
+
);
|
|
5754
|
+
const response = parseAuthorResponse(value);
|
|
5755
|
+
if (response.edits.length > limit) {
|
|
5756
|
+
throw new Error(
|
|
5757
|
+
`llmPolicyEditProposer: author returned ${response.edits.length} edits for ${limit} candidate slots`
|
|
5758
|
+
);
|
|
5759
|
+
}
|
|
5760
|
+
const edits = response.edits.map(
|
|
5761
|
+
(draft) => bindAuthoredEdit(
|
|
5762
|
+
draft,
|
|
5763
|
+
findingByKey,
|
|
5764
|
+
opts.targetSurface,
|
|
5765
|
+
allowedPathSet,
|
|
5766
|
+
objectiveByKey,
|
|
5767
|
+
ctx.incumbentOutcome?.composite ?? ctx.baselineOutcome?.composite
|
|
5768
|
+
)
|
|
5769
|
+
);
|
|
5770
|
+
return policyEditProposer({
|
|
5771
|
+
edits,
|
|
5772
|
+
admission: admissionMode === "strict" ? opts.admission : {
|
|
5773
|
+
minScore: 0,
|
|
5774
|
+
minExpectedGain: 0,
|
|
5775
|
+
allowHighRisk: true,
|
|
5776
|
+
requireEvidence: true
|
|
5777
|
+
},
|
|
5778
|
+
maxCandidates: limit,
|
|
5779
|
+
onAdmission: opts.onAdmission
|
|
5780
|
+
}).propose(ctx);
|
|
5781
|
+
}
|
|
5782
|
+
};
|
|
5783
|
+
}
|
|
5784
|
+
function projectPolicyEditHistory(history, options = {}) {
|
|
5785
|
+
const limits = validateHistoryLimits(options);
|
|
5786
|
+
const objectiveByKey = new Map(
|
|
5787
|
+
(options.objectives ? validateObjectives(options.objectives) : []).map((objective) => [
|
|
5788
|
+
objective.key,
|
|
5789
|
+
objective
|
|
5790
|
+
])
|
|
5791
|
+
);
|
|
5792
|
+
const scenarioIds = createScenarioIdProjector(limits.scenarioIdTransform);
|
|
5793
|
+
registerHistoryScenarioIds(history.slice(-limits.maxGenerations), scenarioIds);
|
|
5794
|
+
return projectPolicyEditHistoryWithProjector(history, limits, scenarioIds, objectiveByKey);
|
|
5795
|
+
}
|
|
5796
|
+
function projectPolicyEditHistoryWithProjector(history, limits, scenarioIds, objectiveByKey) {
|
|
5797
|
+
const retainedHistory = history.slice(-limits.maxGenerations);
|
|
5798
|
+
const candidateByHash = new Map(
|
|
5799
|
+
retainedHistory.flatMap(
|
|
5800
|
+
(record) => record.candidates.map((candidate) => [candidate.surfaceHash, candidate])
|
|
5801
|
+
)
|
|
5802
|
+
);
|
|
5803
|
+
return retainedHistory.map((record) => {
|
|
5804
|
+
const candidates = selectHistoryCandidates(record, limits.maxCandidatesPerGeneration);
|
|
5805
|
+
const hashes = new Set(candidates.map((candidate) => candidate.surfaceHash));
|
|
5806
|
+
return {
|
|
5807
|
+
generationIndex: record.generationIndex,
|
|
5808
|
+
promoted: record.promoted.filter((hash) => hashes.has(hash)).map((hash) => scenarioIds.sanitize(hash)),
|
|
5809
|
+
candidates: candidates.map(
|
|
5810
|
+
(candidate) => projectHistoryCandidate(
|
|
5811
|
+
candidate,
|
|
5812
|
+
scenarioIds,
|
|
5813
|
+
limits.maxScenariosPerCandidate,
|
|
5814
|
+
candidate.parentSurfaceHash ? candidateByHash.get(candidate.parentSurfaceHash)?.scenarios : void 0,
|
|
5815
|
+
objectiveByKey
|
|
5816
|
+
)
|
|
5817
|
+
)
|
|
5818
|
+
};
|
|
5819
|
+
});
|
|
5820
|
+
}
|
|
5821
|
+
function selectHistoryCandidates(record, limit) {
|
|
5822
|
+
const promotionOrder = new Map(record.promoted.map((hash, index) => [hash, index]));
|
|
5823
|
+
const promoted = [...record.candidates].filter((candidate) => promotionOrder.has(candidate.surfaceHash)).sort((a, b) => promotionOrder.get(a.surfaceHash) - promotionOrder.get(b.surfaceHash));
|
|
5824
|
+
const selected = promoted.slice(0, limit);
|
|
5825
|
+
const selectedHashes = new Set(selected.map((candidate) => candidate.surfaceHash));
|
|
5826
|
+
const remaining = [...record.candidates].filter((candidate) => !promotionOrder.has(candidate.surfaceHash)).sort((a, b) => b.composite - a.composite || a.surfaceHash.localeCompare(b.surfaceHash));
|
|
5827
|
+
let high = 0;
|
|
5828
|
+
let low = remaining.length - 1;
|
|
5829
|
+
let takeLow = selected.length > 0;
|
|
5830
|
+
while (selected.length < limit && high <= low) {
|
|
5831
|
+
const candidate = takeLow ? remaining[low--] : remaining[high++];
|
|
5832
|
+
takeLow = !takeLow;
|
|
5833
|
+
if (!candidate || selectedHashes.has(candidate.surfaceHash)) continue;
|
|
5834
|
+
selected.push(candidate);
|
|
5835
|
+
selectedHashes.add(candidate.surfaceHash);
|
|
5836
|
+
}
|
|
5837
|
+
return selected;
|
|
5838
|
+
}
|
|
5839
|
+
function projectHistoryCandidate(candidate, scenarioIds, maxScenarios, parentScenarios, objectiveByKey) {
|
|
5840
|
+
const referenceByScenario = parentScenarios ? new Map(parentScenarios.map((scenario) => [scenario.scenarioId, scenario.composite])) : void 0;
|
|
5841
|
+
const selectedScenarios = selectPolicyEditAuthorRows(candidate.scenarios, {
|
|
5842
|
+
limit: maxScenarios,
|
|
5843
|
+
...referenceByScenario ? { referenceByScenario } : {}
|
|
5844
|
+
});
|
|
5845
|
+
const validatedRecord = candidate.candidateRecord ? validatePolicyEditCandidateRecord(candidate.candidateRecord) : void 0;
|
|
5846
|
+
return {
|
|
5847
|
+
surfaceHash: scenarioIds.sanitize(candidate.surfaceHash),
|
|
5848
|
+
parentSurfaceHash: candidate.parentSurfaceHash ? scenarioIds.sanitize(candidate.parentSurfaceHash) : null,
|
|
5849
|
+
parentComposite: candidate.parentComposite ?? null,
|
|
5850
|
+
label: candidate.label ? scenarioIds.sanitize(candidate.label) : null,
|
|
5851
|
+
rationale: candidate.rationale ? scenarioIds.sanitize(candidate.rationale) : null,
|
|
5852
|
+
composite: candidate.composite,
|
|
5853
|
+
observedDeltaFromParent: candidate.observedDeltaFromParent ?? null,
|
|
5854
|
+
eligibleForPromotion: candidate.eligibleForPromotion ?? null,
|
|
5855
|
+
coverage: candidate.coverage ? {
|
|
5856
|
+
expectedCells: candidate.coverage.expectedCells,
|
|
5857
|
+
scorableCells: candidate.coverage.scorableCells,
|
|
5858
|
+
// `cellId` embeds the raw scenario ID. The aggregate reason is useful
|
|
5859
|
+
// for search, but the identifier must not bypass scenarioIdTransform.
|
|
5860
|
+
unscorableCells: [...candidate.coverage.unscorableCells].sort((a, b) => a.cellId.localeCompare(b.cellId)).slice(0, maxScenarios).map((cell) => ({ reason: scenarioIds.sanitize(cell.reason) }))
|
|
5861
|
+
} : null,
|
|
5862
|
+
// GenerationCandidate.ci95 is currently a placeholder [composite, composite],
|
|
5863
|
+
// not a measured interval. Keep it out of author context until it is real.
|
|
5864
|
+
dimensions: sanitizeDimensions(candidate.dimensions, scenarioIds),
|
|
5865
|
+
scenarios: selectedScenarios.map((scenario) => {
|
|
5866
|
+
return {
|
|
5867
|
+
scenarioId: scenarioIds.project(scenario.scenarioId),
|
|
5868
|
+
composite: scenario.composite,
|
|
5869
|
+
notes: scenario.notes ? scenarioIds.sanitize(scenario.notes) : null
|
|
5870
|
+
};
|
|
5871
|
+
}),
|
|
5872
|
+
candidateEdit: validatedRecord ? summarizeCandidateEdit(validatedRecord, scenarioIds) : null,
|
|
5873
|
+
forecastCalibration: forecastCalibration(candidate, validatedRecord, objectiveByKey)
|
|
5874
|
+
};
|
|
5875
|
+
}
|
|
5876
|
+
function projectOutcome(outcome, scenarioIds, maxScenarios, reference = void 0) {
|
|
5877
|
+
if (!outcome) return null;
|
|
5878
|
+
const referenceByScenario = reference ? new Map(reference.scenarios.map((scenario) => [scenario.scenarioId, scenario.composite])) : void 0;
|
|
5879
|
+
const selectedScenarios = selectPolicyEditAuthorRows(outcome.scenarios, {
|
|
5880
|
+
limit: maxScenarios,
|
|
5881
|
+
...referenceByScenario ? { referenceByScenario } : {}
|
|
5882
|
+
});
|
|
5883
|
+
return {
|
|
5884
|
+
split: "search",
|
|
5885
|
+
generation: outcome.generation,
|
|
5886
|
+
surfaceHash: scenarioIds.sanitize(outcome.surfaceHash),
|
|
5887
|
+
composite: outcome.composite,
|
|
5888
|
+
dimensions: sanitizeDimensions(outcome.dimensions, scenarioIds),
|
|
5889
|
+
scenarios: selectedScenarios.map((scenario) => {
|
|
5890
|
+
return {
|
|
5891
|
+
scenarioId: scenarioIds.project(scenario.scenarioId),
|
|
5892
|
+
composite: scenario.composite,
|
|
5893
|
+
notes: scenario.notes ? scenarioIds.sanitize(scenario.notes) : null
|
|
5894
|
+
};
|
|
5895
|
+
}),
|
|
5896
|
+
coverage: { ...outcome.coverage }
|
|
5897
|
+
};
|
|
5898
|
+
}
|
|
5899
|
+
function createScenarioIdProjector(transform) {
|
|
5900
|
+
const aliases = /* @__PURE__ */ new Map();
|
|
5901
|
+
const originals = /* @__PURE__ */ new Map();
|
|
5902
|
+
return {
|
|
5903
|
+
project(scenarioId) {
|
|
5904
|
+
const known = aliases.get(scenarioId);
|
|
5905
|
+
if (known) return known;
|
|
5906
|
+
const alias = transform(scenarioId);
|
|
5907
|
+
if (!alias || alias.trim() !== alias) {
|
|
5908
|
+
throw new Error(
|
|
5909
|
+
"llmPolicyEditProposer: scenarioIdTransform must return a trimmed non-empty string"
|
|
5910
|
+
);
|
|
5911
|
+
}
|
|
5912
|
+
const collision = originals.get(alias);
|
|
5913
|
+
if (collision && collision !== scenarioId) {
|
|
5914
|
+
throw new Error(
|
|
5915
|
+
`llmPolicyEditProposer: scenarioIdTransform collision for '${collision}' and '${scenarioId}'`
|
|
5916
|
+
);
|
|
5917
|
+
}
|
|
5918
|
+
const aliasIsAnotherOriginal = aliases.has(alias) && alias !== scenarioId;
|
|
5919
|
+
const originalIsAnotherAlias = originals.has(scenarioId) && originals.get(scenarioId) !== scenarioId;
|
|
5920
|
+
if (aliasIsAnotherOriginal || originalIsAnotherAlias) {
|
|
5921
|
+
throw new Error(
|
|
5922
|
+
"llmPolicyEditProposer: scenarioIdTransform aliases overlap raw scenario IDs"
|
|
5923
|
+
);
|
|
5924
|
+
}
|
|
5925
|
+
aliases.set(scenarioId, alias);
|
|
5926
|
+
originals.set(alias, scenarioId);
|
|
5927
|
+
return alias;
|
|
5928
|
+
},
|
|
5929
|
+
sanitize(text) {
|
|
5930
|
+
const originalsByLength = [...aliases.keys()].sort((a, b) => b.length - a.length);
|
|
5931
|
+
if (originalsByLength.length === 0) return text;
|
|
5932
|
+
const pattern = new RegExp(
|
|
5933
|
+
`(^|[^A-Za-z0-9_-])(${originalsByLength.map(escapeRegExp).join("|")})(?=$|[^A-Za-z0-9_-])`,
|
|
5934
|
+
"g"
|
|
5935
|
+
);
|
|
5936
|
+
return text.replace(
|
|
5937
|
+
pattern,
|
|
5938
|
+
(_match, prefix, original) => `${prefix}${aliases.get(original) ?? original}`
|
|
5939
|
+
);
|
|
5940
|
+
}
|
|
5941
|
+
};
|
|
5942
|
+
}
|
|
5943
|
+
function escapeRegExp(value) {
|
|
5944
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
5945
|
+
}
|
|
5946
|
+
function sourceKey(surfaceHash2, generation) {
|
|
5947
|
+
return `${surfaceHash2}@${generation}`;
|
|
5948
|
+
}
|
|
5949
|
+
function measuredSourceMeasurements(ctx) {
|
|
5950
|
+
const measurements = /* @__PURE__ */ new Map();
|
|
5951
|
+
const add = (measurement) => {
|
|
5952
|
+
measurements.set(sourceKey(measurement.surfaceHash, measurement.generation), measurement);
|
|
5953
|
+
};
|
|
5954
|
+
if (ctx.baselineOutcome) {
|
|
5955
|
+
add({
|
|
5956
|
+
surfaceHash: ctx.baselineOutcome.surfaceHash,
|
|
5957
|
+
generation: ctx.baselineOutcome.generation,
|
|
5958
|
+
composite: ctx.baselineOutcome.composite,
|
|
5959
|
+
parentComposite: null,
|
|
5960
|
+
observedDeltaFromParent: null,
|
|
5961
|
+
eligibleForPromotion: true,
|
|
5962
|
+
coverage: { ...ctx.baselineOutcome.coverage }
|
|
5963
|
+
});
|
|
5964
|
+
}
|
|
5965
|
+
for (const record of ctx.history) {
|
|
5966
|
+
for (const candidate of record.candidates) {
|
|
5967
|
+
add({
|
|
5968
|
+
surfaceHash: candidate.surfaceHash,
|
|
5969
|
+
generation: record.generationIndex,
|
|
5970
|
+
composite: candidate.composite,
|
|
5971
|
+
parentComposite: candidate.parentComposite ?? null,
|
|
5972
|
+
observedDeltaFromParent: candidate.observedDeltaFromParent ?? null,
|
|
5973
|
+
eligibleForPromotion: candidate.eligibleForPromotion === true,
|
|
5974
|
+
coverage: candidate.coverage ? {
|
|
5975
|
+
expectedCells: candidate.coverage.expectedCells,
|
|
5976
|
+
scorableCells: candidate.coverage.scorableCells
|
|
5977
|
+
} : { expectedCells: 0, scorableCells: 0 }
|
|
5978
|
+
});
|
|
5979
|
+
}
|
|
5980
|
+
}
|
|
5981
|
+
if (ctx.incumbentOutcome) {
|
|
5982
|
+
const generation = ctx.incumbentOutcome.generation;
|
|
5983
|
+
const key = sourceKey(ctx.incumbentOutcome.surfaceHash, generation);
|
|
5984
|
+
if (!measurements.has(key)) {
|
|
5985
|
+
add({
|
|
5986
|
+
surfaceHash: ctx.incumbentOutcome.surfaceHash,
|
|
5987
|
+
generation,
|
|
5988
|
+
composite: ctx.incumbentOutcome.composite,
|
|
5989
|
+
parentComposite: null,
|
|
5990
|
+
observedDeltaFromParent: null,
|
|
5991
|
+
eligibleForPromotion: true,
|
|
5992
|
+
coverage: { ...ctx.incumbentOutcome.coverage }
|
|
5993
|
+
});
|
|
5994
|
+
}
|
|
5995
|
+
}
|
|
5996
|
+
return measurements;
|
|
5997
|
+
}
|
|
5998
|
+
function validateFindingSource(source, measured) {
|
|
5999
|
+
if (source.kind === "global") {
|
|
6000
|
+
requireNonEmpty(source.label, "global finding source label");
|
|
6001
|
+
return;
|
|
6002
|
+
}
|
|
6003
|
+
if (!measured.has(sourceKey(source.surfaceHash, source.generation))) {
|
|
6004
|
+
throw new Error(
|
|
6005
|
+
`llmPolicyEditProposer: finding source ${source.surfaceHash}@${source.generation} is not a measured surface`
|
|
6006
|
+
);
|
|
6007
|
+
}
|
|
6008
|
+
}
|
|
6009
|
+
function sameFindingSource(a, b) {
|
|
6010
|
+
if (a.kind !== b.kind) return false;
|
|
6011
|
+
return a.kind === "surface" && b.kind === "surface" ? a.surfaceHash === b.surfaceHash && a.generation === b.generation : a.kind === "global" && b.kind === "global" && a.label === b.label;
|
|
6012
|
+
}
|
|
6013
|
+
function summarizeCandidateEdit(record, scenarioIds) {
|
|
6014
|
+
const edit = record.policyEdit;
|
|
6015
|
+
return {
|
|
6016
|
+
editId: edit.editId,
|
|
6017
|
+
axis: edit.axis,
|
|
6018
|
+
target: sanitizeAuthorValue(edit.target, scenarioIds),
|
|
6019
|
+
change: sanitizeAuthorValue(edit.change, scenarioIds),
|
|
6020
|
+
claim: scenarioIds.sanitize(edit.claim),
|
|
6021
|
+
expectedGain: sanitizeAuthorValue(edit.expectedGain, scenarioIds),
|
|
6022
|
+
confidence: edit.confidence,
|
|
6023
|
+
risk: edit.risk,
|
|
6024
|
+
sourceFindingIds: edit.source.findingIds.map((id) => scenarioIds.sanitize(id)),
|
|
6025
|
+
rationale: edit.rationale ? scenarioIds.sanitize(edit.rationale) : null,
|
|
6026
|
+
validationPlan: edit.validationPlan ? scenarioIds.sanitize(edit.validationPlan) : null
|
|
6027
|
+
};
|
|
6028
|
+
}
|
|
6029
|
+
function sanitizeAuthorValue(value, scenarioIds) {
|
|
6030
|
+
if (typeof value === "string") return scenarioIds.sanitize(value);
|
|
6031
|
+
if (Array.isArray(value)) return value.map((item) => sanitizeAuthorValue(item, scenarioIds));
|
|
6032
|
+
if (value && typeof value === "object") {
|
|
6033
|
+
return Object.fromEntries(
|
|
6034
|
+
Object.entries(value).map(([key, child]) => [
|
|
6035
|
+
scenarioIds.sanitize(key),
|
|
6036
|
+
sanitizeAuthorValue(child, scenarioIds)
|
|
6037
|
+
])
|
|
6038
|
+
);
|
|
6039
|
+
}
|
|
6040
|
+
return value;
|
|
6041
|
+
}
|
|
6042
|
+
function sanitizeDimensions(dimensions, scenarioIds) {
|
|
6043
|
+
const sanitized = /* @__PURE__ */ new Map();
|
|
6044
|
+
for (const [key, value] of Object.entries(dimensions)) {
|
|
6045
|
+
const projected = scenarioIds.sanitize(key);
|
|
6046
|
+
const prior = sanitized.get(projected);
|
|
6047
|
+
if (prior && prior.original !== key) {
|
|
6048
|
+
throw new Error(
|
|
6049
|
+
`llmPolicyEditProposer: pseudonymized dimension key collision for '${prior.original}' and '${key}'`
|
|
6050
|
+
);
|
|
6051
|
+
}
|
|
6052
|
+
sanitized.set(projected, { original: key, value });
|
|
6053
|
+
}
|
|
6054
|
+
return Object.fromEntries([...sanitized].map(([key, entry]) => [key, entry.value]));
|
|
6055
|
+
}
|
|
6056
|
+
function forecastCalibration(candidate, record, objectiveByKey) {
|
|
6057
|
+
if (!record || candidate.observedDeltaFromParent === void 0) return null;
|
|
6058
|
+
const forecast = record.policyEdit.expectedGain;
|
|
6059
|
+
const objective = objectiveByKey.get(forecast.metric);
|
|
6060
|
+
if (!objective || objective.key !== "search.composite") return null;
|
|
6061
|
+
if (forecast.direction !== objective.direction || forecast.unit !== objective.unit) return null;
|
|
6062
|
+
if (forecast.amount > objective.scale.max - objective.scale.min) return null;
|
|
6063
|
+
const predictedDelta = forecast.amount;
|
|
6064
|
+
return {
|
|
6065
|
+
objectiveKey: objective.key,
|
|
6066
|
+
predictedDelta,
|
|
6067
|
+
observedDelta: candidate.observedDeltaFromParent,
|
|
6068
|
+
residual: candidate.observedDeltaFromParent - predictedDelta
|
|
6069
|
+
};
|
|
6070
|
+
}
|
|
6071
|
+
function assertSearchOutcome(outcome, field) {
|
|
6072
|
+
if (outcome && outcome.split !== "search") {
|
|
6073
|
+
throw new Error(`llmPolicyEditProposer: ${field} must be a search-split outcome`);
|
|
6074
|
+
}
|
|
6075
|
+
}
|
|
6076
|
+
function assertMeasuredCompositesInScale(ctx, objective) {
|
|
6077
|
+
const assertInScale = (value, field) => {
|
|
6078
|
+
if (!Number.isFinite(value) || value < objective.scale.min || value > objective.scale.max) {
|
|
6079
|
+
throw new Error(
|
|
6080
|
+
`llmPolicyEditProposer: ${field} ${value} is outside objective '${objective.key}' scale [${objective.scale.min}, ${objective.scale.max}]`
|
|
6081
|
+
);
|
|
6082
|
+
}
|
|
6083
|
+
};
|
|
6084
|
+
const assertOutcome = (outcome, field) => {
|
|
6085
|
+
if (!outcome) return;
|
|
6086
|
+
assertInScale(outcome.composite, `${field}.composite`);
|
|
6087
|
+
for (const [index, scenario] of outcome.scenarios.entries()) {
|
|
6088
|
+
assertInScale(scenario.composite, `${field}.scenarios[${index}].composite`);
|
|
6089
|
+
}
|
|
6090
|
+
};
|
|
6091
|
+
assertOutcome(ctx.baselineOutcome, "baselineOutcome");
|
|
6092
|
+
assertOutcome(ctx.incumbentOutcome, "incumbentOutcome");
|
|
6093
|
+
for (const [generationIndex, generation] of ctx.history.entries()) {
|
|
6094
|
+
for (const [candidateIndex, candidate] of generation.candidates.entries()) {
|
|
6095
|
+
const field = `history[${generationIndex}].candidates[${candidateIndex}]`;
|
|
6096
|
+
assertInScale(candidate.composite, `${field}.composite`);
|
|
6097
|
+
if (candidate.parentComposite !== void 0) {
|
|
6098
|
+
assertInScale(candidate.parentComposite, `${field}.parentComposite`);
|
|
6099
|
+
}
|
|
6100
|
+
for (const [scenarioIndex, scenario] of candidate.scenarios.entries()) {
|
|
6101
|
+
assertInScale(scenario.composite, `${field}.scenarios[${scenarioIndex}].composite`);
|
|
6102
|
+
}
|
|
6103
|
+
}
|
|
6104
|
+
}
|
|
6105
|
+
}
|
|
6106
|
+
function assertSurfaceIsTaskAgnostic(value, scenarioIds) {
|
|
6107
|
+
const serialized = JSON.stringify(value);
|
|
6108
|
+
if (scenarioIds.sanitize(serialized) !== serialized) {
|
|
6109
|
+
throw new Error(
|
|
6110
|
+
"llmPolicyEditProposer: current JSON surface or signature contains a raw scenario identifier"
|
|
6111
|
+
);
|
|
6112
|
+
}
|
|
6113
|
+
}
|
|
6114
|
+
function registerOutcomeScenarioIds(outcome, scenarioIds) {
|
|
6115
|
+
for (const scenario of outcome?.scenarios ?? []) scenarioIds.project(scenario.scenarioId);
|
|
6116
|
+
}
|
|
6117
|
+
function registerHistoryScenarioIds(history, scenarioIds) {
|
|
6118
|
+
for (const record of history) {
|
|
6119
|
+
for (const candidate of record.candidates) {
|
|
6120
|
+
for (const scenario of candidate.scenarios) scenarioIds.project(scenario.scenarioId);
|
|
6121
|
+
for (const cell of candidate.coverage?.unscorableCells ?? []) {
|
|
6122
|
+
const separator = cell.cellId.lastIndexOf(":");
|
|
6123
|
+
if (separator <= 0 || !/^\d+$/.test(cell.cellId.slice(separator + 1))) continue;
|
|
6124
|
+
scenarioIds.project(cell.cellId.slice(0, separator));
|
|
6125
|
+
}
|
|
6126
|
+
}
|
|
6127
|
+
}
|
|
6128
|
+
}
|
|
6129
|
+
function validateHistoryLimits(options) {
|
|
6130
|
+
const maxGenerations = options.maxGenerations ?? DEFAULT_POLICY_EDIT_HISTORY_LIMITS.generations;
|
|
6131
|
+
const maxCandidatesPerGeneration = options.maxCandidatesPerGeneration ?? DEFAULT_POLICY_EDIT_HISTORY_LIMITS.candidatesPerGeneration;
|
|
6132
|
+
const maxScenariosPerCandidate = options.maxScenariosPerCandidate ?? DEFAULT_POLICY_EDIT_HISTORY_LIMITS.scenariosPerCandidate;
|
|
6133
|
+
if (!Number.isSafeInteger(maxGenerations) || maxGenerations <= 0) {
|
|
6134
|
+
throw new Error("llmPolicyEditProposer: maxHistoryGenerations must be a positive safe integer");
|
|
6135
|
+
}
|
|
6136
|
+
if (!Number.isSafeInteger(maxCandidatesPerGeneration) || maxCandidatesPerGeneration <= 0) {
|
|
6137
|
+
throw new Error(
|
|
6138
|
+
"llmPolicyEditProposer: maxHistoryCandidatesPerGeneration must be a positive safe integer"
|
|
6139
|
+
);
|
|
6140
|
+
}
|
|
6141
|
+
if (!Number.isSafeInteger(maxScenariosPerCandidate) || maxScenariosPerCandidate <= 0) {
|
|
6142
|
+
throw new Error(
|
|
6143
|
+
"llmPolicyEditProposer: maxScenariosPerCandidate must be a positive safe integer"
|
|
6144
|
+
);
|
|
6145
|
+
}
|
|
6146
|
+
return {
|
|
6147
|
+
maxGenerations,
|
|
6148
|
+
maxCandidatesPerGeneration,
|
|
6149
|
+
maxScenariosPerCandidate,
|
|
6150
|
+
scenarioIdTransform: options.scenarioIdTransform ?? ((scenarioId) => scenarioId)
|
|
6151
|
+
};
|
|
6152
|
+
}
|
|
6153
|
+
function validateObjectives(inputs) {
|
|
6154
|
+
if (inputs.length === 0) {
|
|
6155
|
+
throw new Error("llmPolicyEditProposer: objectives must not be empty");
|
|
6156
|
+
}
|
|
6157
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6158
|
+
return inputs.map((input) => {
|
|
6159
|
+
requireNonEmpty(input.key, "objective key");
|
|
6160
|
+
if (seen.has(input.key)) {
|
|
6161
|
+
throw new Error(`llmPolicyEditProposer: duplicate objective '${input.key}'`);
|
|
6162
|
+
}
|
|
6163
|
+
seen.add(input.key);
|
|
6164
|
+
if (input.split !== "search") {
|
|
6165
|
+
throw new Error(`llmPolicyEditProposer: objective '${input.key}' must use the search split`);
|
|
6166
|
+
}
|
|
6167
|
+
if (input.key !== "search.composite") {
|
|
6168
|
+
throw new Error(
|
|
6169
|
+
`llmPolicyEditProposer: objective '${input.key}' is not yet measurable; use 'search.composite'`
|
|
6170
|
+
);
|
|
6171
|
+
}
|
|
6172
|
+
if (input.direction !== "increase") {
|
|
6173
|
+
throw new Error(
|
|
6174
|
+
`llmPolicyEditProposer: objective '${input.key}' must increase because search promotes larger composite scores`
|
|
6175
|
+
);
|
|
6176
|
+
}
|
|
6177
|
+
if (!Number.isFinite(input.scale.min) || !Number.isFinite(input.scale.max) || input.scale.max <= input.scale.min) {
|
|
6178
|
+
throw new Error(`llmPolicyEditProposer: objective '${input.key}' has an invalid scale`);
|
|
6179
|
+
}
|
|
6180
|
+
if (input.unit !== "score") {
|
|
6181
|
+
throw new Error(`llmPolicyEditProposer: objective '${input.key}' must use raw score deltas`);
|
|
6182
|
+
}
|
|
6183
|
+
return {
|
|
6184
|
+
key: input.key,
|
|
6185
|
+
split: "search",
|
|
6186
|
+
direction: input.direction,
|
|
6187
|
+
scale: { ...input.scale },
|
|
6188
|
+
unit: input.unit
|
|
6189
|
+
};
|
|
6190
|
+
});
|
|
6191
|
+
}
|
|
6192
|
+
function positiveLimit(value, field) {
|
|
6193
|
+
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
6194
|
+
throw new Error(`llmPolicyEditProposer: ${field} must be a positive safe integer`);
|
|
6195
|
+
}
|
|
6196
|
+
return value;
|
|
6197
|
+
}
|
|
6198
|
+
function parseAuthorResponse(value) {
|
|
6199
|
+
const parsed = PolicyEditAuthorResponseSchema.safeParse(value);
|
|
6200
|
+
if (parsed.success) return parsed.data;
|
|
6201
|
+
const issues = parsed.error.issues.map((issue) => `${issue.path.join(".") || "<root>"}: ${issue.message}`).join("; ");
|
|
6202
|
+
throw new Error(`llmPolicyEditProposer: invalid PolicyEdit response: ${issues}`);
|
|
6203
|
+
}
|
|
6204
|
+
function bindAuthoredEdit(draft, findingByKey, targetSurface, allowedPaths, objectiveByKey, currentComposite) {
|
|
6205
|
+
if (draft.target.surface !== targetSurface) {
|
|
6206
|
+
throw new Error(
|
|
6207
|
+
`llmPolicyEditProposer: target surface '${draft.target.surface}' does not match '${targetSurface}'`
|
|
6208
|
+
);
|
|
6209
|
+
}
|
|
6210
|
+
if (draft.target.path !== draft.change.path) {
|
|
6211
|
+
throw new Error("llmPolicyEditProposer: target.path must equal change.path");
|
|
6212
|
+
}
|
|
6213
|
+
if (!allowedPaths.has(draft.change.path)) {
|
|
6214
|
+
throw new Error(
|
|
6215
|
+
`llmPolicyEditProposer: JSON path '${draft.change.path}' is outside allowedJsonPaths`
|
|
6216
|
+
);
|
|
6217
|
+
}
|
|
6218
|
+
const cited = draft.source.findingKeys.map((findingKey) => {
|
|
6219
|
+
const finding = findingByKey.get(findingKey);
|
|
6220
|
+
if (!finding) {
|
|
6221
|
+
throw new Error(
|
|
6222
|
+
`llmPolicyEditProposer: edit cites unknown or uncitable finding key '${findingKey}'`
|
|
6223
|
+
);
|
|
6224
|
+
}
|
|
6225
|
+
return finding;
|
|
6226
|
+
});
|
|
6227
|
+
const evidenceRefs = uniqueEvidenceRefs(cited.flatMap((finding) => finding.evidenceRefs));
|
|
6228
|
+
if (evidenceRefs.length === 0) {
|
|
6229
|
+
throw new Error("llmPolicyEditProposer: authored edit has no cited evidence");
|
|
6230
|
+
}
|
|
6231
|
+
const objective = objectiveByKey.get(draft.expectedGain.metric);
|
|
6232
|
+
if (!objective) {
|
|
6233
|
+
throw new Error(
|
|
6234
|
+
`llmPolicyEditProposer: unknown forecast objective '${draft.expectedGain.metric}'`
|
|
6235
|
+
);
|
|
6236
|
+
}
|
|
6237
|
+
if (draft.expectedGain.direction !== objective.direction) {
|
|
6238
|
+
throw new Error(
|
|
6239
|
+
`llmPolicyEditProposer: forecast direction for '${objective.key}' must be '${objective.direction}'`
|
|
6240
|
+
);
|
|
6241
|
+
}
|
|
6242
|
+
if (draft.expectedGain.unit !== objective.unit) {
|
|
6243
|
+
throw new Error(
|
|
6244
|
+
`llmPolicyEditProposer: forecast unit for '${objective.key}' must be '${objective.unit}'`
|
|
6245
|
+
);
|
|
6246
|
+
}
|
|
6247
|
+
const maxGain = currentComposite === void 0 ? objective.scale.max - objective.scale.min : objective.scale.max - currentComposite;
|
|
6248
|
+
if (draft.expectedGain.amount > maxGain) {
|
|
6249
|
+
throw new Error(
|
|
6250
|
+
`llmPolicyEditProposer: forecast amount for '${objective.key}' exceeds the available score headroom`
|
|
6251
|
+
);
|
|
6252
|
+
}
|
|
6253
|
+
const expectedGain = {
|
|
6254
|
+
metric: draft.expectedGain.metric,
|
|
6255
|
+
direction: draft.expectedGain.direction,
|
|
6256
|
+
amount: draft.expectedGain.amount,
|
|
6257
|
+
...draft.expectedGain.unit ? { unit: draft.expectedGain.unit } : {},
|
|
6258
|
+
...draft.expectedGain.rationale ? { rationale: draft.expectedGain.rationale } : {}
|
|
6259
|
+
};
|
|
6260
|
+
const init = {
|
|
6261
|
+
axis: draft.axis,
|
|
6262
|
+
target: {
|
|
6263
|
+
surface: draft.target.surface,
|
|
6264
|
+
path: draft.target.path,
|
|
6265
|
+
...draft.target.label ? { label: draft.target.label } : {}
|
|
6266
|
+
},
|
|
6267
|
+
change: draft.change,
|
|
6268
|
+
claim: draft.claim,
|
|
6269
|
+
expectedGain,
|
|
6270
|
+
confidence: draft.confidence,
|
|
6271
|
+
risk: draft.risk,
|
|
6272
|
+
source: {
|
|
6273
|
+
findingIds: [...new Set(cited.map((finding) => finding.finding.finding_id))],
|
|
6274
|
+
analystIds: [...new Set(cited.map((finding) => finding.finding.analyst_id))],
|
|
6275
|
+
evidenceRefs
|
|
6276
|
+
},
|
|
6277
|
+
...draft.rationale ? { rationale: draft.rationale } : {},
|
|
6278
|
+
...draft.validationPlan ? { validationPlan: draft.validationPlan } : {}
|
|
6279
|
+
};
|
|
6280
|
+
return makePolicyEdit(init);
|
|
6281
|
+
}
|
|
6282
|
+
function parseJsonSurface(surface) {
|
|
6283
|
+
if (typeof surface !== "string") {
|
|
6284
|
+
throw new Error("llmPolicyEditProposer: currentSurface must be serialized JSON");
|
|
6285
|
+
}
|
|
6286
|
+
let parsed;
|
|
6287
|
+
try {
|
|
6288
|
+
parsed = JSON.parse(surface);
|
|
6289
|
+
} catch {
|
|
6290
|
+
throw new Error("llmPolicyEditProposer: currentSurface must be valid JSON");
|
|
6291
|
+
}
|
|
6292
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
6293
|
+
throw new Error("llmPolicyEditProposer: currentSurface JSON root must be an object");
|
|
6294
|
+
}
|
|
6295
|
+
return parsed;
|
|
6296
|
+
}
|
|
6297
|
+
function citableFindings(inputs, measuredSources, limit) {
|
|
6298
|
+
if (inputs.length === 0) {
|
|
6299
|
+
throw new Error("llmPolicyEditProposer: at least one analyst finding is required");
|
|
6300
|
+
}
|
|
6301
|
+
const findings = [];
|
|
6302
|
+
for (const input of inputs) {
|
|
6303
|
+
if (!isPolicyEditFindingInput(input)) {
|
|
6304
|
+
throw new Error(
|
|
6305
|
+
"llmPolicyEditProposer: ctx.findings must contain attributed PolicyEditFindingInput rows"
|
|
6306
|
+
);
|
|
6307
|
+
}
|
|
6308
|
+
findings.push(input.finding);
|
|
6309
|
+
}
|
|
6310
|
+
assertNoJudgeVerdict(findings, "llmPolicyEditProposer");
|
|
6311
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
6312
|
+
for (const input of inputs) {
|
|
6313
|
+
validateFindingSource(input.source, measuredSources);
|
|
6314
|
+
if (input.finding.evidence_refs.length === 0) continue;
|
|
6315
|
+
const existing = grouped.get(input.finding.finding_id);
|
|
6316
|
+
if (existing) {
|
|
6317
|
+
if (existing.finding.analyst_id !== input.finding.analyst_id || existing.finding.area !== input.finding.area || existing.finding.claim !== input.finding.claim || existing.finding.subject !== input.finding.subject) {
|
|
6318
|
+
throw new Error(
|
|
6319
|
+
`llmPolicyEditProposer: finding '${input.finding.finding_id}' has conflicting content`
|
|
6320
|
+
);
|
|
6321
|
+
}
|
|
6322
|
+
if (!existing.sources.some((source) => sameFindingSource(source, input.source))) {
|
|
6323
|
+
existing.sources.push(input.source);
|
|
6324
|
+
}
|
|
6325
|
+
existing.evidenceRefs = uniqueEvidenceRefs([
|
|
6326
|
+
...existing.evidenceRefs,
|
|
6327
|
+
...input.finding.evidence_refs
|
|
6328
|
+
]);
|
|
6329
|
+
continue;
|
|
6330
|
+
}
|
|
6331
|
+
grouped.set(input.finding.finding_id, {
|
|
6332
|
+
finding: input.finding,
|
|
6333
|
+
sources: [input.source],
|
|
6334
|
+
evidenceRefs: uniqueEvidenceRefs(input.finding.evidence_refs)
|
|
6335
|
+
});
|
|
6336
|
+
}
|
|
6337
|
+
if (grouped.size === 0) {
|
|
6338
|
+
throw new Error("llmPolicyEditProposer: no evidence-bearing findings are available");
|
|
6339
|
+
}
|
|
6340
|
+
const severityRank = {
|
|
6341
|
+
critical: 0,
|
|
6342
|
+
high: 1,
|
|
6343
|
+
medium: 2,
|
|
6344
|
+
low: 3,
|
|
6345
|
+
info: 4
|
|
6346
|
+
};
|
|
6347
|
+
return [...grouped.values()].sort(
|
|
6348
|
+
(a, b) => severityRank[a.finding.severity] - severityRank[b.finding.severity] || b.finding.confidence - a.finding.confidence || a.finding.finding_id.localeCompare(b.finding.finding_id)
|
|
6349
|
+
).slice(0, limit);
|
|
6350
|
+
}
|
|
6351
|
+
function isAnalystFindingLike2(input) {
|
|
6352
|
+
if (!input || typeof input !== "object") return false;
|
|
6353
|
+
const value = input;
|
|
6354
|
+
return typeof value.finding_id === "string" && typeof value.analyst_id === "string" && typeof value.claim === "string" && Array.isArray(value.evidence_refs);
|
|
6355
|
+
}
|
|
6356
|
+
function isPolicyEditFindingInput(input) {
|
|
6357
|
+
if (!input || typeof input !== "object") return false;
|
|
6358
|
+
const value = input;
|
|
6359
|
+
return isAnalystFindingLike2(value.finding) && isFindingSource(value.source);
|
|
6360
|
+
}
|
|
6361
|
+
function isFindingSource(input) {
|
|
6362
|
+
if (!input || typeof input !== "object") return false;
|
|
6363
|
+
const value = input;
|
|
6364
|
+
if (value.kind === "surface") {
|
|
6365
|
+
return typeof value.surfaceHash === "string" && Number.isSafeInteger(value.generation);
|
|
6366
|
+
}
|
|
6367
|
+
return value.kind === "global" && typeof value.label === "string" && value.label.trim().length > 0;
|
|
6368
|
+
}
|
|
6369
|
+
function renderFinding(context, findingKey, scenarioIds, measuredSources) {
|
|
6370
|
+
const { finding } = context;
|
|
6371
|
+
return {
|
|
6372
|
+
findingKey,
|
|
6373
|
+
sources: context.sources.map(
|
|
6374
|
+
(source) => source.kind === "surface" ? {
|
|
6375
|
+
...measuredSources.get(sourceKey(source.surfaceHash, source.generation)),
|
|
6376
|
+
surfaceHash: scenarioIds.sanitize(source.surfaceHash),
|
|
6377
|
+
kind: "surface"
|
|
6378
|
+
} : { kind: "global", label: scenarioIds.sanitize(source.label) }
|
|
6379
|
+
),
|
|
6380
|
+
analystId: scenarioIds.sanitize(finding.analyst_id),
|
|
6381
|
+
area: scenarioIds.sanitize(finding.area),
|
|
6382
|
+
severity: finding.severity,
|
|
6383
|
+
subject: finding.subject ? scenarioIds.sanitize(finding.subject) : null,
|
|
6384
|
+
claim: scenarioIds.sanitize(finding.claim),
|
|
6385
|
+
rationale: finding.rationale ? scenarioIds.sanitize(finding.rationale) : null,
|
|
6386
|
+
recommendedAction: finding.recommended_action ? scenarioIds.sanitize(finding.recommended_action) : null,
|
|
6387
|
+
validationPlan: finding.validation_plan ? scenarioIds.sanitize(finding.validation_plan) : null,
|
|
6388
|
+
confidence: finding.confidence,
|
|
6389
|
+
evidenceRefs: context.evidenceRefs.map((ref) => ({
|
|
6390
|
+
kind: ref.kind,
|
|
6391
|
+
uri: scenarioIds.sanitize(ref.uri),
|
|
6392
|
+
excerpt: ref.excerpt ? scenarioIds.sanitize(ref.excerpt) : null
|
|
6393
|
+
}))
|
|
6394
|
+
};
|
|
6395
|
+
}
|
|
6396
|
+
function uniqueEvidenceRefs(refs) {
|
|
6397
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6398
|
+
return refs.filter((ref) => {
|
|
6399
|
+
const key = JSON.stringify([ref.kind, ref.uri, ref.excerpt ?? null]);
|
|
6400
|
+
if (seen.has(key)) return false;
|
|
6401
|
+
seen.add(key);
|
|
6402
|
+
return true;
|
|
6403
|
+
});
|
|
6404
|
+
}
|
|
6405
|
+
function validateAllowedJsonPaths(paths) {
|
|
6406
|
+
if (paths.length === 0) {
|
|
6407
|
+
throw new Error("llmPolicyEditProposer: allowedJsonPaths must not be empty");
|
|
6408
|
+
}
|
|
6409
|
+
for (const path of paths) {
|
|
6410
|
+
if (!path || path.trim() !== path) {
|
|
6411
|
+
throw new Error(
|
|
6412
|
+
"llmPolicyEditProposer: allowedJsonPaths must contain trimmed non-empty paths"
|
|
6413
|
+
);
|
|
6414
|
+
}
|
|
6415
|
+
}
|
|
6416
|
+
if (new Set(paths).size !== paths.length) {
|
|
6417
|
+
throw new Error("llmPolicyEditProposer: allowedJsonPaths must be unique");
|
|
6418
|
+
}
|
|
6419
|
+
return [...paths];
|
|
6420
|
+
}
|
|
6421
|
+
function requireNonEmpty(value, field) {
|
|
6422
|
+
if (!value || value.trim() !== value) {
|
|
6423
|
+
throw new Error(`llmPolicyEditProposer: ${field} must be a trimmed non-empty string`);
|
|
6424
|
+
}
|
|
6425
|
+
}
|
|
6426
|
+
|
|
5267
6427
|
// src/campaign/proposers/memory.ts
|
|
5268
6428
|
var BLOCK_START2 = "<!-- BEGIN curated-memory (auto-managed by memoryCurationProposer) -->";
|
|
5269
6429
|
var BLOCK_END2 = "<!-- END curated-memory -->";
|
|
@@ -5344,69 +6504,6 @@ ${block}
|
|
|
5344
6504
|
};
|
|
5345
6505
|
}
|
|
5346
6506
|
|
|
5347
|
-
// src/campaign/proposers/policy-edit.ts
|
|
5348
|
-
function policyEditProposer(opts = {}) {
|
|
5349
|
-
return {
|
|
5350
|
-
kind: "policy-edit",
|
|
5351
|
-
async propose(ctx) {
|
|
5352
|
-
const edits = materializePolicyEdits(opts.edits ?? ctx.findings, opts.findingOptions);
|
|
5353
|
-
const limit = Math.max(
|
|
5354
|
-
0,
|
|
5355
|
-
Math.min(opts.maxCandidates ?? ctx.populationSize, ctx.populationSize)
|
|
5356
|
-
);
|
|
5357
|
-
const out = [];
|
|
5358
|
-
if (limit === 0) return out;
|
|
5359
|
-
for (const edit of edits) {
|
|
5360
|
-
const admission = admitPolicyEdit(edit, opts.admission);
|
|
5361
|
-
opts.onAdmission?.(admission);
|
|
5362
|
-
if (admission.decision !== "admit") continue;
|
|
5363
|
-
const surface = coerceCandidateSurface(applyPolicyEditToSurface(ctx.currentSurface, edit));
|
|
5364
|
-
if (sameSurface(ctx.currentSurface, surface)) continue;
|
|
5365
|
-
out.push({
|
|
5366
|
-
surface,
|
|
5367
|
-
label: `policy-edit:${edit.axis}`,
|
|
5368
|
-
rationale: `${edit.editId} expected ${edit.expectedGain.direction} ${edit.expectedGain.metric} by ${edit.expectedGain.amount}; source findings [${edit.source.findingIds.join(", ")}]`
|
|
5369
|
-
});
|
|
5370
|
-
if (out.length >= limit) break;
|
|
5371
|
-
}
|
|
5372
|
-
return out;
|
|
5373
|
-
}
|
|
5374
|
-
};
|
|
5375
|
-
}
|
|
5376
|
-
function materializePolicyEdits(inputs, findingOptions) {
|
|
5377
|
-
const edits = [];
|
|
5378
|
-
const findings = [];
|
|
5379
|
-
for (const input of inputs) {
|
|
5380
|
-
if (isPolicyEdit(input)) {
|
|
5381
|
-
edits.push(input);
|
|
5382
|
-
} else if (isAnalystFindingLike(input)) {
|
|
5383
|
-
findings.push(input);
|
|
5384
|
-
}
|
|
5385
|
-
}
|
|
5386
|
-
if (findings.length > 0) edits.push(...policyEditsFromFindings(findings, findingOptions));
|
|
5387
|
-
return edits;
|
|
5388
|
-
}
|
|
5389
|
-
function isAnalystFindingLike(input) {
|
|
5390
|
-
if (!input || typeof input !== "object") return false;
|
|
5391
|
-
const obj = input;
|
|
5392
|
-
return typeof obj.finding_id === "string" && typeof obj.analyst_id === "string" && typeof obj.claim === "string" && Array.isArray(obj.evidence_refs);
|
|
5393
|
-
}
|
|
5394
|
-
function coerceCandidateSurface(surface) {
|
|
5395
|
-
if (typeof surface === "string") return surface;
|
|
5396
|
-
if (surface && typeof surface === "object") {
|
|
5397
|
-
const obj = surface;
|
|
5398
|
-
if (obj.kind === "code" && typeof obj.worktreeRef === "string") {
|
|
5399
|
-
assertCodeSurfaceIdentity(surface);
|
|
5400
|
-
return surface;
|
|
5401
|
-
}
|
|
5402
|
-
return JSON.stringify(surface, null, 2);
|
|
5403
|
-
}
|
|
5404
|
-
throw new Error("policyEditProposer: policy edit produced an unsupported surface");
|
|
5405
|
-
}
|
|
5406
|
-
function sameSurface(a, b) {
|
|
5407
|
-
return surfaceContentHash(a) === surfaceContentHash(b);
|
|
5408
|
-
}
|
|
5409
|
-
|
|
5410
6507
|
// src/campaign/proposers/trace-analyst.ts
|
|
5411
6508
|
import { ai } from "@ax-llm/ax";
|
|
5412
6509
|
function renderFindings(findings) {
|
|
@@ -5518,7 +6615,7 @@ function selectDiscriminative(signals, k, opts) {
|
|
|
5518
6615
|
import { createHash as createHash7 } from "crypto";
|
|
5519
6616
|
import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
|
|
5520
6617
|
import { resolve as resolve2 } from "path";
|
|
5521
|
-
import { z as
|
|
6618
|
+
import { z as z3 } from "zod";
|
|
5522
6619
|
|
|
5523
6620
|
// src/campaign/search-ledger-errors.ts
|
|
5524
6621
|
var SearchLedgerError = class extends ValidationError {
|
|
@@ -5545,7 +6642,7 @@ import {
|
|
|
5545
6642
|
} from "fs";
|
|
5546
6643
|
import { hostname } from "os";
|
|
5547
6644
|
import { dirname as dirname2 } from "path";
|
|
5548
|
-
import { z } from "zod";
|
|
6645
|
+
import { z as z2 } from "zod";
|
|
5549
6646
|
function appendSearchLedgerLine(path, line) {
|
|
5550
6647
|
mkdirSync2(dirname2(path), { recursive: true });
|
|
5551
6648
|
const fd = openSync(path, constants.O_CREAT | constants.O_WRONLY | constants.O_APPEND, 384);
|
|
@@ -5639,10 +6736,10 @@ function readOwner(lockPath) {
|
|
|
5639
6736
|
cause: error
|
|
5640
6737
|
});
|
|
5641
6738
|
}
|
|
5642
|
-
const parsed =
|
|
5643
|
-
pid:
|
|
5644
|
-
host:
|
|
5645
|
-
nonce:
|
|
6739
|
+
const parsed = z2.object({
|
|
6740
|
+
pid: z2.number().int().positive().safe(),
|
|
6741
|
+
host: z2.string().trim().min(1),
|
|
6742
|
+
nonce: z2.string().trim().min(1)
|
|
5646
6743
|
}).strict().safeParse(raw);
|
|
5647
6744
|
if (!parsed.success) {
|
|
5648
6745
|
throw new SearchLedgerIntegrityError(
|
|
@@ -5672,82 +6769,82 @@ function unlinkIfExists(path) {
|
|
|
5672
6769
|
|
|
5673
6770
|
// src/campaign/search-ledger.ts
|
|
5674
6771
|
var SEARCH_LEDGER_SCHEMA = "tangle.search-ledger.v1";
|
|
5675
|
-
var NON_EMPTY =
|
|
5676
|
-
var HASH =
|
|
5677
|
-
var LINEAGE_NODE_ID =
|
|
5678
|
-
var IMMUTABLE_REVISION =
|
|
5679
|
-
var ISO_TIMESTAMP =
|
|
5680
|
-
var NON_NEGATIVE_INT =
|
|
5681
|
-
var FINITE_NUMBER =
|
|
5682
|
-
var ArtifactRefSchema =
|
|
6772
|
+
var NON_EMPTY = z3.string().min(1).refine((value) => value.trim() === value, "must not contain surrounding whitespace");
|
|
6773
|
+
var HASH = z3.string().regex(/^sha256:[a-f0-9]{64}$/);
|
|
6774
|
+
var LINEAGE_NODE_ID = z3.string().regex(/^[a-f0-9]{16}$/);
|
|
6775
|
+
var IMMUTABLE_REVISION = z3.string().regex(/^(?:[a-f0-9]{40}|[a-f0-9]{64}|sha256:[a-f0-9]{64}|sha512:[A-Za-z0-9+/=]+)$/);
|
|
6776
|
+
var ISO_TIMESTAMP = z3.string().regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/).refine((value) => Number.isFinite(Date.parse(value)), "invalid timestamp");
|
|
6777
|
+
var NON_NEGATIVE_INT = z3.number().int().nonnegative().safe();
|
|
6778
|
+
var FINITE_NUMBER = z3.number().finite();
|
|
6779
|
+
var ArtifactRefSchema = z3.object({
|
|
5683
6780
|
role: NON_EMPTY,
|
|
5684
6781
|
uri: NON_EMPTY,
|
|
5685
6782
|
sha256: HASH,
|
|
5686
6783
|
byteLength: NON_NEGATIVE_INT
|
|
5687
6784
|
}).strict();
|
|
5688
|
-
var SourceRefSchema =
|
|
6785
|
+
var SourceRefSchema = z3.object({
|
|
5689
6786
|
uri: NON_EMPTY,
|
|
5690
6787
|
revision: IMMUTABLE_REVISION
|
|
5691
6788
|
}).strict();
|
|
5692
|
-
var FailureReasonSchema =
|
|
6789
|
+
var FailureReasonSchema = z3.object({
|
|
5693
6790
|
code: NON_EMPTY,
|
|
5694
6791
|
message: NON_EMPTY
|
|
5695
6792
|
}).strict();
|
|
5696
6793
|
var EventBaseShape = {
|
|
5697
6794
|
eventId: NON_EMPTY,
|
|
5698
6795
|
occurredAt: ISO_TIMESTAMP,
|
|
5699
|
-
artifacts:
|
|
6796
|
+
artifacts: z3.array(ArtifactRefSchema).min(1)
|
|
5700
6797
|
};
|
|
5701
|
-
var OperationKindSchema =
|
|
6798
|
+
var OperationKindSchema = z3.enum([
|
|
5702
6799
|
"candidate-generation",
|
|
5703
6800
|
"analysis",
|
|
5704
6801
|
"selection",
|
|
5705
6802
|
"judge",
|
|
5706
6803
|
"other"
|
|
5707
6804
|
]);
|
|
5708
|
-
var SearchPlannedSchema =
|
|
6805
|
+
var SearchPlannedSchema = z3.object({
|
|
5709
6806
|
...EventBaseShape,
|
|
5710
|
-
kind:
|
|
5711
|
-
plan:
|
|
5712
|
-
candidateSlots:
|
|
5713
|
-
|
|
6807
|
+
kind: z3.literal("search-planned"),
|
|
6808
|
+
plan: z3.object({
|
|
6809
|
+
candidateSlots: z3.array(
|
|
6810
|
+
z3.object({
|
|
5714
6811
|
slotId: NON_EMPTY,
|
|
5715
6812
|
generationOperationId: NON_EMPTY
|
|
5716
6813
|
}).strict()
|
|
5717
6814
|
).min(1),
|
|
5718
|
-
tasks:
|
|
5719
|
-
|
|
6815
|
+
tasks: z3.array(
|
|
6816
|
+
z3.object({
|
|
5720
6817
|
taskId: NON_EMPTY,
|
|
5721
6818
|
source: SourceRefSchema,
|
|
5722
6819
|
benchmark: SourceRefSchema,
|
|
5723
|
-
maxAttempts:
|
|
6820
|
+
maxAttempts: z3.number().int().positive().safe()
|
|
5724
6821
|
}).strict()
|
|
5725
6822
|
).min(1),
|
|
5726
|
-
operations:
|
|
5727
|
-
|
|
6823
|
+
operations: z3.array(
|
|
6824
|
+
z3.object({
|
|
5728
6825
|
operationId: NON_EMPTY,
|
|
5729
6826
|
kind: OperationKindSchema
|
|
5730
6827
|
}).strict()
|
|
5731
6828
|
).min(1)
|
|
5732
6829
|
}).strict()
|
|
5733
6830
|
}).strict();
|
|
5734
|
-
var CandidateRegisteredSchema =
|
|
6831
|
+
var CandidateRegisteredSchema = z3.object({
|
|
5735
6832
|
...EventBaseShape,
|
|
5736
|
-
kind:
|
|
6833
|
+
kind: z3.literal("candidate-registered"),
|
|
5737
6834
|
slotId: NON_EMPTY,
|
|
5738
6835
|
generationOperationId: NON_EMPTY,
|
|
5739
6836
|
candidateId: NON_EMPTY,
|
|
5740
|
-
lineage:
|
|
6837
|
+
lineage: z3.object({
|
|
5741
6838
|
lineageNodeId: LINEAGE_NODE_ID,
|
|
5742
|
-
parentCandidateIds:
|
|
6839
|
+
parentCandidateIds: z3.array(NON_EMPTY),
|
|
5743
6840
|
generation: NON_NEGATIVE_INT,
|
|
5744
6841
|
proposer: NON_EMPTY,
|
|
5745
6842
|
proposerSource: SourceRefSchema
|
|
5746
6843
|
}).strict(),
|
|
5747
|
-
surfaces:
|
|
5748
|
-
|
|
6844
|
+
surfaces: z3.array(
|
|
6845
|
+
z3.object({
|
|
5749
6846
|
surfaceId: NON_EMPTY,
|
|
5750
|
-
kind:
|
|
6847
|
+
kind: z3.enum([
|
|
5751
6848
|
"prompt",
|
|
5752
6849
|
"tool-contract",
|
|
5753
6850
|
"runtime-config",
|
|
@@ -5761,69 +6858,69 @@ var CandidateRegisteredSchema = z2.object({
|
|
|
5761
6858
|
}).strict()
|
|
5762
6859
|
).min(1)
|
|
5763
6860
|
}).strict();
|
|
5764
|
-
var CandidateSlotClosedSchema =
|
|
6861
|
+
var CandidateSlotClosedSchema = z3.object({
|
|
5765
6862
|
...EventBaseShape,
|
|
5766
|
-
kind:
|
|
6863
|
+
kind: z3.literal("candidate-slot-closed"),
|
|
5767
6864
|
slotId: NON_EMPTY,
|
|
5768
6865
|
generationOperationId: NON_EMPTY,
|
|
5769
6866
|
reason: FailureReasonSchema
|
|
5770
6867
|
}).strict();
|
|
5771
|
-
var KnownTokensSchema =
|
|
5772
|
-
status:
|
|
6868
|
+
var KnownTokensSchema = z3.object({
|
|
6869
|
+
status: z3.literal("known"),
|
|
5773
6870
|
inputTokens: NON_NEGATIVE_INT,
|
|
5774
6871
|
outputTokens: NON_NEGATIVE_INT,
|
|
5775
6872
|
cachedTokens: NON_NEGATIVE_INT
|
|
5776
6873
|
}).strict();
|
|
5777
|
-
var UnknownSchema =
|
|
5778
|
-
status:
|
|
6874
|
+
var UnknownSchema = z3.object({
|
|
6875
|
+
status: z3.literal("unknown"),
|
|
5779
6876
|
reason: NON_EMPTY
|
|
5780
6877
|
}).strict();
|
|
5781
|
-
var KnownCostSchema =
|
|
5782
|
-
status:
|
|
5783
|
-
usd:
|
|
5784
|
-
source:
|
|
6878
|
+
var KnownCostSchema = z3.object({
|
|
6879
|
+
status: z3.literal("known"),
|
|
6880
|
+
usd: z3.number().finite().nonnegative(),
|
|
6881
|
+
source: z3.enum(["provider", "pricing-table", "free"])
|
|
5785
6882
|
}).strict().superRefine((cost, ctx) => {
|
|
5786
6883
|
if (cost.source === "free" && cost.usd !== 0) {
|
|
5787
6884
|
ctx.addIssue({ code: "custom", message: "free cost source must have usd 0" });
|
|
5788
6885
|
}
|
|
5789
6886
|
});
|
|
5790
|
-
var UnknownCostSchema =
|
|
5791
|
-
status:
|
|
5792
|
-
knownLowerBoundUsd:
|
|
6887
|
+
var UnknownCostSchema = z3.object({
|
|
6888
|
+
status: z3.literal("unknown"),
|
|
6889
|
+
knownLowerBoundUsd: z3.number().finite().nonnegative(),
|
|
5793
6890
|
reason: NON_EMPTY
|
|
5794
6891
|
}).strict();
|
|
5795
|
-
var AccountingSchema =
|
|
5796
|
-
tokens:
|
|
5797
|
-
cost:
|
|
6892
|
+
var AccountingSchema = z3.object({
|
|
6893
|
+
tokens: z3.discriminatedUnion("status", [KnownTokensSchema, UnknownSchema]),
|
|
6894
|
+
cost: z3.discriminatedUnion("status", [KnownCostSchema, UnknownCostSchema])
|
|
5798
6895
|
}).strict();
|
|
5799
|
-
var MetricsSchema =
|
|
6896
|
+
var MetricsSchema = z3.record(NON_EMPTY, FINITE_NUMBER).superRefine((metrics, ctx) => {
|
|
5800
6897
|
for (const key of Object.keys(metrics)) {
|
|
5801
6898
|
if (key === "__proto__" || key === "constructor" || key === "prototype") {
|
|
5802
6899
|
ctx.addIssue({ code: "custom", message: `unsafe metric key ${key}` });
|
|
5803
6900
|
}
|
|
5804
6901
|
}
|
|
5805
6902
|
});
|
|
5806
|
-
var OutcomeSchema =
|
|
5807
|
-
|
|
5808
|
-
status:
|
|
6903
|
+
var OutcomeSchema = z3.discriminatedUnion("status", [
|
|
6904
|
+
z3.object({
|
|
6905
|
+
status: z3.literal("passed"),
|
|
5809
6906
|
score: FINITE_NUMBER,
|
|
5810
6907
|
metrics: MetricsSchema
|
|
5811
6908
|
}).strict(),
|
|
5812
|
-
|
|
5813
|
-
status:
|
|
6909
|
+
z3.object({
|
|
6910
|
+
status: z3.literal("failed"),
|
|
5814
6911
|
score: FINITE_NUMBER,
|
|
5815
6912
|
metrics: MetricsSchema,
|
|
5816
6913
|
failure: FailureReasonSchema
|
|
5817
6914
|
}).strict(),
|
|
5818
|
-
|
|
5819
|
-
status:
|
|
6915
|
+
z3.object({
|
|
6916
|
+
status: z3.literal("errored"),
|
|
5820
6917
|
metrics: MetricsSchema,
|
|
5821
|
-
error: FailureReasonSchema.extend({ retryable:
|
|
6918
|
+
error: FailureReasonSchema.extend({ retryable: z3.boolean() }).strict()
|
|
5822
6919
|
}).strict()
|
|
5823
6920
|
]);
|
|
5824
|
-
var EffectSchema =
|
|
5825
|
-
|
|
5826
|
-
status:
|
|
6921
|
+
var EffectSchema = z3.discriminatedUnion("status", [
|
|
6922
|
+
z3.object({
|
|
6923
|
+
status: z3.literal("measured"),
|
|
5827
6924
|
metric: NON_EMPTY,
|
|
5828
6925
|
baselineValue: FINITE_NUMBER,
|
|
5829
6926
|
candidateValue: FINITE_NUMBER,
|
|
@@ -5835,17 +6932,17 @@ var EffectSchema = z2.discriminatedUnion("status", [
|
|
|
5835
6932
|
ctx.addIssue({ code: "custom", message: "delta must equal candidateValue - baselineValue" });
|
|
5836
6933
|
}
|
|
5837
6934
|
}),
|
|
5838
|
-
|
|
5839
|
-
status:
|
|
6935
|
+
z3.object({
|
|
6936
|
+
status: z3.literal("not-measured"),
|
|
5840
6937
|
reason: NON_EMPTY
|
|
5841
6938
|
}).strict()
|
|
5842
6939
|
]);
|
|
5843
|
-
var SurfaceEvidenceSchema =
|
|
6940
|
+
var SurfaceEvidenceSchema = z3.object({
|
|
5844
6941
|
surfaceId: NON_EMPTY,
|
|
5845
|
-
fired:
|
|
6942
|
+
fired: z3.boolean(),
|
|
5846
6943
|
firingCount: NON_NEGATIVE_INT,
|
|
5847
6944
|
effect: EffectSchema,
|
|
5848
|
-
evidence:
|
|
6945
|
+
evidence: z3.array(ArtifactRefSchema).min(1)
|
|
5849
6946
|
}).strict().superRefine((evidence, ctx) => {
|
|
5850
6947
|
if (evidence.fired && evidence.firingCount === 0) {
|
|
5851
6948
|
ctx.addIssue({ code: "custom", message: "a fired surface must have firingCount >= 1" });
|
|
@@ -5863,15 +6960,15 @@ var SurfaceEvidenceSchema = z2.object({
|
|
|
5863
6960
|
});
|
|
5864
6961
|
}
|
|
5865
6962
|
});
|
|
5866
|
-
var TaskAttemptedSchema =
|
|
6963
|
+
var TaskAttemptedSchema = z3.object({
|
|
5867
6964
|
...EventBaseShape,
|
|
5868
|
-
kind:
|
|
6965
|
+
kind: z3.literal("task-attempted"),
|
|
5869
6966
|
candidateId: NON_EMPTY,
|
|
5870
6967
|
runId: NON_EMPTY,
|
|
5871
6968
|
attemptIndex: NON_NEGATIVE_INT,
|
|
5872
|
-
task:
|
|
5873
|
-
identity:
|
|
5874
|
-
model:
|
|
6969
|
+
task: z3.object({ taskId: NON_EMPTY, source: SourceRefSchema }).strict(),
|
|
6970
|
+
identity: z3.object({
|
|
6971
|
+
model: z3.object({
|
|
5875
6972
|
provider: NON_EMPTY,
|
|
5876
6973
|
snapshot: NON_EMPTY.refine(
|
|
5877
6974
|
modelHasSnapshot,
|
|
@@ -5883,17 +6980,17 @@ var TaskAttemptedSchema = z2.object({
|
|
|
5883
6980
|
}).strict(),
|
|
5884
6981
|
outcome: OutcomeSchema,
|
|
5885
6982
|
accounting: AccountingSchema,
|
|
5886
|
-
surfaceEvidence:
|
|
6983
|
+
surfaceEvidence: z3.array(SurfaceEvidenceSchema).min(1)
|
|
5887
6984
|
}).strict();
|
|
5888
|
-
var SearchOperationRecordedSchema =
|
|
6985
|
+
var SearchOperationRecordedSchema = z3.object({
|
|
5889
6986
|
...EventBaseShape,
|
|
5890
|
-
kind:
|
|
6987
|
+
kind: z3.literal("search-operation-recorded"),
|
|
5891
6988
|
operationId: NON_EMPTY,
|
|
5892
6989
|
operationKind: OperationKindSchema,
|
|
5893
|
-
execution:
|
|
5894
|
-
|
|
5895
|
-
kind:
|
|
5896
|
-
model:
|
|
6990
|
+
execution: z3.discriminatedUnion("kind", [
|
|
6991
|
+
z3.object({
|
|
6992
|
+
kind: z3.literal("model"),
|
|
6993
|
+
model: z3.object({
|
|
5897
6994
|
provider: NON_EMPTY,
|
|
5898
6995
|
snapshot: NON_EMPTY.refine(
|
|
5899
6996
|
modelHasSnapshot,
|
|
@@ -5902,51 +6999,51 @@ var SearchOperationRecordedSchema = z2.object({
|
|
|
5902
6999
|
}).strict(),
|
|
5903
7000
|
source: SourceRefSchema
|
|
5904
7001
|
}).strict(),
|
|
5905
|
-
|
|
5906
|
-
kind:
|
|
7002
|
+
z3.object({
|
|
7003
|
+
kind: z3.literal("deterministic"),
|
|
5907
7004
|
source: SourceRefSchema
|
|
5908
7005
|
}).strict()
|
|
5909
7006
|
]),
|
|
5910
|
-
outcome:
|
|
5911
|
-
|
|
5912
|
-
|
|
5913
|
-
status:
|
|
7007
|
+
outcome: z3.discriminatedUnion("status", [
|
|
7008
|
+
z3.object({ status: z3.literal("completed") }).strict(),
|
|
7009
|
+
z3.object({
|
|
7010
|
+
status: z3.literal("partial"),
|
|
5914
7011
|
failure: FailureReasonSchema
|
|
5915
7012
|
}).strict(),
|
|
5916
|
-
|
|
5917
|
-
status:
|
|
7013
|
+
z3.object({
|
|
7014
|
+
status: z3.literal("failed"),
|
|
5918
7015
|
failure: FailureReasonSchema
|
|
5919
7016
|
}).strict()
|
|
5920
7017
|
]),
|
|
5921
7018
|
accounting: AccountingSchema
|
|
5922
7019
|
}).strict();
|
|
5923
|
-
var CandidateDecidedSchema =
|
|
7020
|
+
var CandidateDecidedSchema = z3.object({
|
|
5924
7021
|
...EventBaseShape,
|
|
5925
|
-
kind:
|
|
7022
|
+
kind: z3.literal("candidate-decided"),
|
|
5926
7023
|
candidateId: NON_EMPTY,
|
|
5927
|
-
decision:
|
|
5928
|
-
|
|
5929
|
-
|
|
5930
|
-
status:
|
|
7024
|
+
decision: z3.discriminatedUnion("status", [
|
|
7025
|
+
z3.object({ status: z3.literal("selected") }).strict(),
|
|
7026
|
+
z3.object({
|
|
7027
|
+
status: z3.literal("rejected"),
|
|
5931
7028
|
reason: FailureReasonSchema
|
|
5932
7029
|
}).strict()
|
|
5933
7030
|
])
|
|
5934
7031
|
}).strict();
|
|
5935
|
-
var SearchCompletedSchema =
|
|
7032
|
+
var SearchCompletedSchema = z3.object({
|
|
5936
7033
|
...EventBaseShape,
|
|
5937
|
-
kind:
|
|
5938
|
-
result:
|
|
5939
|
-
|
|
5940
|
-
status:
|
|
7034
|
+
kind: z3.literal("search-completed"),
|
|
7035
|
+
result: z3.discriminatedUnion("status", [
|
|
7036
|
+
z3.object({
|
|
7037
|
+
status: z3.literal("selected"),
|
|
5941
7038
|
candidateId: NON_EMPTY
|
|
5942
7039
|
}).strict(),
|
|
5943
|
-
|
|
5944
|
-
status:
|
|
7040
|
+
z3.object({
|
|
7041
|
+
status: z3.literal("all-rejected"),
|
|
5945
7042
|
reason: FailureReasonSchema
|
|
5946
7043
|
}).strict()
|
|
5947
7044
|
])
|
|
5948
7045
|
}).strict();
|
|
5949
|
-
var EventSchema =
|
|
7046
|
+
var EventSchema = z3.discriminatedUnion("kind", [
|
|
5950
7047
|
SearchPlannedSchema,
|
|
5951
7048
|
CandidateRegisteredSchema,
|
|
5952
7049
|
CandidateSlotClosedSchema,
|
|
@@ -5955,11 +7052,11 @@ var EventSchema = z2.discriminatedUnion("kind", [
|
|
|
5955
7052
|
CandidateDecidedSchema,
|
|
5956
7053
|
SearchCompletedSchema
|
|
5957
7054
|
]);
|
|
5958
|
-
var EntrySchema =
|
|
5959
|
-
schema:
|
|
7055
|
+
var EntrySchema = z3.object({
|
|
7056
|
+
schema: z3.literal(SEARCH_LEDGER_SCHEMA),
|
|
5960
7057
|
campaignId: NON_EMPTY,
|
|
5961
7058
|
sequence: NON_NEGATIVE_INT,
|
|
5962
|
-
previousHash:
|
|
7059
|
+
previousHash: z3.union([HASH, z3.null()]),
|
|
5963
7060
|
event: EventSchema,
|
|
5964
7061
|
entryHash: HASH
|
|
5965
7062
|
}).strict();
|
|
@@ -7297,8 +8394,13 @@ export {
|
|
|
7297
8394
|
aceProposer,
|
|
7298
8395
|
compositeProposer,
|
|
7299
8396
|
haloProposer,
|
|
7300
|
-
memoryCurationProposer,
|
|
7301
8397
|
policyEditProposer,
|
|
8398
|
+
selectPolicyEditAuthorRows,
|
|
8399
|
+
assertPolicyEditAuthorContextBudget,
|
|
8400
|
+
DEFAULT_POLICY_EDIT_HISTORY_LIMITS,
|
|
8401
|
+
llmPolicyEditProposer,
|
|
8402
|
+
projectPolicyEditHistory,
|
|
8403
|
+
memoryCurationProposer,
|
|
7302
8404
|
traceAnalystProposer,
|
|
7303
8405
|
scoreDiscrimination,
|
|
7304
8406
|
selectDiscriminative,
|
|
@@ -7316,4 +8418,4 @@ export {
|
|
|
7316
8418
|
verifyCodeSurface,
|
|
7317
8419
|
resolveWorktreePath
|
|
7318
8420
|
};
|
|
7319
|
-
//# sourceMappingURL=chunk-
|
|
8421
|
+
//# sourceMappingURL=chunk-GSW3OBHK.js.map
|