@remnic/bench 9.6.19 → 9.6.20

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/index.js CHANGED
@@ -8972,11 +8972,560 @@ function createClaudeCliProvider(config, deps) {
8972
8972
  // src/providers/codex-cli.ts
8973
8973
  import { spawn as spawn2 } from "child_process";
8974
8974
  import { createHash as createHash5, randomUUID } from "crypto";
8975
- import { mkdir as mkdir5, mkdtemp as mkdtemp3, readFile as readFile6, rm as rm3, writeFile as writeFile5 } from "fs/promises";
8975
+ import { mkdir as mkdir6, mkdtemp as mkdtemp3, readFile as readFile7, rm as rm3, writeFile as writeFile6 } from "fs/promises";
8976
+ import os5 from "os";
8977
+ import path8 from "path";
8978
+
8979
+ // src/judges/memcorrect-rubrics.ts
8980
+ var OPENAI_RESPONSES_JUDGE_RUBRIC_VERSION = "openai-responses-bench-v1";
8981
+ var MEMCORRECT_CORRECTION_ACCEPTANCE_RUBRIC_VERSION = "memcorrect-correction-acceptance-v1";
8982
+ var MEMCORRECT_STALE_HARM_RUBRIC_VERSION = "memcorrect-stale-memory-harm-v1";
8983
+ var GENERAL_ANSWER_JUDGE_RUBRIC = [
8984
+ "Grade the predicted benchmark answer against the reference answer.",
8985
+ "A score of 1 means fully correct, 0 means fully incorrect, and values between 0 and 1 mean partially correct.",
8986
+ "Do not reward unsupported claims. Ignore harmless wording and formatting differences."
8987
+ ].join(" ");
8988
+ var MEMCORRECT_CORRECTION_ACCEPTANCE_RUBRIC = [
8989
+ "Decide whether the memory system accepted the user's correction.",
8990
+ "Pass only when the corrected fact is reflected and the retired fact is not asserted as current.",
8991
+ "A quotation or correction-history record that clearly marks the retired fact as obsolete is not stale recall.",
8992
+ "Use a score of 1 for accepted, 0 for not accepted, and a fractional score only when the evidence is genuinely ambiguous."
8993
+ ].join(" ");
8994
+ var MEMCORRECT_STALE_HARM_RUBRIC = [
8995
+ "Decide whether the memory system avoided stale-memory harm after a correction.",
8996
+ "Pass only when the answer does not present the retired fact as current and does not act on it.",
8997
+ "Correction provenance may mention the retired fact only when it is explicitly identified as obsolete.",
8998
+ "Use a score of 1 when no stale harm is present, 0 when stale information affected the answer, and a fractional score only for genuinely ambiguous evidence."
8999
+ ].join(" ");
9000
+
9001
+ // src/providers/structured-judge.ts
9002
+ var VERDICT_JSON_SCHEMA = {
9003
+ type: "object",
9004
+ additionalProperties: false,
9005
+ required: ["score", "decision", "reason"],
9006
+ properties: {
9007
+ score: { type: "number", minimum: 0, maximum: 1 },
9008
+ decision: { type: "string", enum: ["pass", "partial", "fail"] },
9009
+ reason: { type: "string" }
9010
+ }
9011
+ };
9012
+ var ASSISTANT_RUBRIC_JSON_SCHEMA = {
9013
+ type: "object",
9014
+ additionalProperties: false,
9015
+ required: ["identity_accuracy", "stance_coherence", "novelty", "calibration", "notes"],
9016
+ properties: {
9017
+ identity_accuracy: { type: "number", minimum: 0, maximum: 5 },
9018
+ stance_coherence: { type: "number", minimum: 0, maximum: 5 },
9019
+ novelty: { type: "number", minimum: 0, maximum: 5 },
9020
+ calibration: { type: "number", minimum: 0, maximum: 5 },
9021
+ notes: { type: "string" }
9022
+ }
9023
+ };
9024
+ var StructuredJudgeError = class extends Error {
9025
+ code;
9026
+ retryable;
9027
+ httpStatus;
9028
+ telemetry;
9029
+ constructor(failure) {
9030
+ super(failure.error.message);
9031
+ this.name = "StructuredJudgeError";
9032
+ this.code = failure.error.code;
9033
+ this.retryable = failure.error.retryable;
9034
+ this.httpStatus = failure.error.httpStatus;
9035
+ this.telemetry = failure.telemetry;
9036
+ }
9037
+ };
9038
+ function isStructuredJudgeProvider(provider) {
9039
+ const candidate = provider;
9040
+ return typeof candidate.judge === "function" && typeof candidate.evaluateAssistantRubric === "function";
9041
+ }
9042
+ function createStructuredBenchJudge(provider, rubricVersion = OPENAI_RESPONSES_JUDGE_RUBRIC_VERSION) {
9043
+ const scoreWithMetrics = async (question, predicted, expected, control) => unwrapJudgeResult(
9044
+ provider,
9045
+ await provider.judge({
9046
+ rubric: GENERAL_ANSWER_JUDGE_RUBRIC,
9047
+ rubricVersion,
9048
+ input: [`QUESTION: ${question}`, `REFERENCE_ANSWER: ${expected}`, `PREDICTED_ANSWER: ${predicted}`].join(
9049
+ "\n\n"
9050
+ ),
9051
+ signal: control?.signal
9052
+ })
9053
+ );
9054
+ const scoreBinaryPrompt = async (prompt, control) => {
9055
+ const result = await provider.judge({
9056
+ rubric: `${GENERAL_ANSWER_JUDGE_RUBRIC} This evaluator is binary: score must be exactly 0 or 1.`,
9057
+ rubricVersion,
9058
+ input: prompt,
9059
+ signal: control?.signal
9060
+ });
9061
+ if (result.ok && result.verdict.score !== 0 && result.verdict.score !== 1) {
9062
+ throwJudgeFailure(provider, {
9063
+ ok: false,
9064
+ error: {
9065
+ code: "malformed_verdict",
9066
+ message: "Structured judge returned a non-binary verdict for a binary rubric.",
9067
+ retryable: false
9068
+ },
9069
+ telemetry: { ...result.telemetry, errorCode: "malformed_verdict" }
9070
+ });
9071
+ }
9072
+ return unwrapJudgeResult(provider, result);
9073
+ };
9074
+ const judgeSpecialized = async (request, rubric, control) => {
9075
+ const result = await provider.judge({
9076
+ rubric: rubric === "correction" ? MEMCORRECT_CORRECTION_ACCEPTANCE_RUBRIC : MEMCORRECT_STALE_HARM_RUBRIC,
9077
+ rubricVersion: rubric === "correction" ? MEMCORRECT_CORRECTION_ACCEPTANCE_RUBRIC_VERSION : MEMCORRECT_STALE_HARM_RUBRIC_VERSION,
9078
+ input: serializeMemCorrectJudgeRequest(request),
9079
+ signal: control?.signal
9080
+ });
9081
+ if (!result.ok) {
9082
+ throwJudgeFailure(provider, result);
9083
+ }
9084
+ const base = unwrapJudgeResult(provider, result);
9085
+ return {
9086
+ ...base,
9087
+ decision: result.verdict.decision,
9088
+ reason: result.verdict.reason,
9089
+ rubricVersion: result.telemetry.rubricVersion
9090
+ };
9091
+ };
9092
+ return {
9093
+ async score(question, predicted, expected, control) {
9094
+ return (await scoreWithMetrics(question, predicted, expected, control)).score;
9095
+ },
9096
+ scoreWithMetrics,
9097
+ scoreBinaryPrompt,
9098
+ judgeMemCorrectCorrectionAcceptance: (request, control) => judgeSpecialized(request, "correction", control),
9099
+ judgeMemCorrectStaleMemoryHarm: (request, control) => judgeSpecialized(request, "stale_harm", control)
9100
+ };
9101
+ }
9102
+ function parseStructuredJudgeVerdict(text) {
9103
+ let parsed;
9104
+ try {
9105
+ parsed = JSON.parse(text);
9106
+ } catch {
9107
+ return null;
9108
+ }
9109
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
9110
+ const candidate = parsed;
9111
+ if (Object.keys(candidate).sort().join(",") !== "decision,reason,score") return null;
9112
+ if (typeof candidate.score !== "number" || !Number.isFinite(candidate.score) || candidate.score < 0 || candidate.score > 1 || candidate.decision !== "pass" && candidate.decision !== "partial" && candidate.decision !== "fail" || typeof candidate.reason !== "string" || candidate.reason.trim().length === 0) {
9113
+ return null;
9114
+ }
9115
+ return {
9116
+ score: candidate.score,
9117
+ decision: candidate.decision,
9118
+ reason: candidate.reason.trim()
9119
+ };
9120
+ }
9121
+ function isValidAssistantRubric(text) {
9122
+ let parsed;
9123
+ try {
9124
+ parsed = JSON.parse(text);
9125
+ } catch {
9126
+ return false;
9127
+ }
9128
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return false;
9129
+ const candidate = parsed;
9130
+ if (Object.keys(candidate).sort().join(",") !== "calibration,identity_accuracy,notes,novelty,stance_coherence") {
9131
+ return false;
9132
+ }
9133
+ return ["identity_accuracy", "stance_coherence", "novelty", "calibration"].every(
9134
+ (key) => typeof candidate[key] === "number" && Number.isFinite(candidate[key]) && candidate[key] >= 0 && candidate[key] <= 5
9135
+ ) && typeof candidate.notes === "string";
9136
+ }
9137
+ function serializeMemCorrectJudgeRequest(request) {
9138
+ return JSON.stringify({
9139
+ taskId: request.taskId,
9140
+ query: request.query,
9141
+ retiredContent: request.retiredContent,
9142
+ correctedContent: request.correctedContent,
9143
+ evidence: {
9144
+ postCorrectionRecall: request.postCorrectionRecall,
9145
+ postMaintenanceRecall: request.postMaintenanceRecall,
9146
+ postReingestRecall: request.postReingestRecall
9147
+ }
9148
+ });
9149
+ }
9150
+ function unwrapJudgeResult(provider, result) {
9151
+ if (!result.ok) {
9152
+ throwJudgeFailure(provider, result);
9153
+ }
9154
+ return {
9155
+ score: result.verdict.score,
9156
+ tokens: {
9157
+ input: result.telemetry.inputTokens,
9158
+ output: result.telemetry.outputTokens
9159
+ },
9160
+ latencyMs: result.telemetry.latencyMs,
9161
+ model: result.telemetry.model
9162
+ };
9163
+ }
9164
+ function throwJudgeFailure(provider, failure) {
9165
+ throw provider.createJudgeError?.(failure) ?? new StructuredJudgeError(failure);
9166
+ }
9167
+
9168
+ // src/providers/codex-credit-budget.ts
9169
+ import { mkdir as mkdir5, open, readFile as readFile6, rename as rename2, rmdir, unlink as unlink3, writeFile as writeFile5 } from "fs/promises";
8976
9170
  import os4 from "os";
8977
9171
  import path7 from "path";
9172
+ var ONE_MILLION = 1e6;
9173
+ var MAX_BOUNDED_CALL_CREDITS = 300;
9174
+ var SOL_MODEL = /^gpt-5\.6-sol$/i;
9175
+ var CREDIT_RATES = [
9176
+ [/^gpt-5\.6-sol$/i, { input: 125, cachedInput: 12.5, output: 750 }],
9177
+ [/^gpt-5\.6-terra$/i, { input: 62.5, cachedInput: 6.25, output: 375 }],
9178
+ [/^gpt-5\.6-luna$/i, { input: 25, cachedInput: 2.5, output: 150 }],
9179
+ [/^gpt-5\.5$/i, { input: 125, cachedInput: 12.5, output: 750 }],
9180
+ [/^gpt-5\.4-mini$/i, { input: 18.75, cachedInput: 1.875, output: 113 }],
9181
+ [/^gpt-5\.4$/i, { input: 62.5, cachedInput: 6.25, output: 375 }],
9182
+ [/^gpt-5\.3-codex$/i, { input: 43.75, cachedInput: 4.375, output: 350 }],
9183
+ [/^gpt-5\.2$/i, { input: 43.75, cachedInput: 4.375, output: 350 }]
9184
+ ];
9185
+ var completionQueue = Promise.resolve();
9186
+ var CodexCreditAccountingError = class extends Error {
9187
+ constructor(message) {
9188
+ super(message);
9189
+ this.name = "CodexCreditAccountingError";
9190
+ }
9191
+ };
9192
+ var CodexCreditDispatchError = class extends Error {
9193
+ constructor(message, options) {
9194
+ super(message, options);
9195
+ this.name = "CodexCreditDispatchError";
9196
+ }
9197
+ };
9198
+ function resolveCodexCreditBudgetConfig(env = process.env) {
9199
+ const rawBudget = env.REMNIC_BENCH_CODEX_CREDIT_BUDGET?.trim();
9200
+ if (!rawBudget) return void 0;
9201
+ const budgetCredits = parsePositiveNumber(
9202
+ rawBudget,
9203
+ "REMNIC_BENCH_CODEX_CREDIT_BUDGET"
9204
+ );
9205
+ const reserveCredits = parseNonNegativeNumber(
9206
+ env.REMNIC_BENCH_CODEX_CREDIT_RESERVE?.trim() ?? "473",
9207
+ "REMNIC_BENCH_CODEX_CREDIT_RESERVE"
9208
+ );
9209
+ if (reserveCredits >= budgetCredits) {
9210
+ throw new Error(
9211
+ "REMNIC_BENCH_CODEX_CREDIT_RESERVE must be smaller than REMNIC_BENCH_CODEX_CREDIT_BUDGET"
9212
+ );
9213
+ }
9214
+ if (reserveCredits < MAX_BOUNDED_CALL_CREDITS) {
9215
+ throw new Error(
9216
+ `REMNIC_BENCH_CODEX_CREDIT_RESERVE must be at least ${MAX_BOUNDED_CALL_CREDITS} credits to cover the conservative maximum cost of the one serialized in-flight call`
9217
+ );
9218
+ }
9219
+ const ledgerPath = path7.resolve(
9220
+ expandHomeRelativePath2(
9221
+ env.REMNIC_BENCH_CODEX_CREDIT_LEDGER?.trim() || ".remnic/bench/codex-credit-ledger.json"
9222
+ )
9223
+ );
9224
+ return {
9225
+ budgetCredits,
9226
+ reserveCredits,
9227
+ ledgerPath,
9228
+ allowSol: /^(?:1|true|yes|on)$/i.test(
9229
+ env.REMNIC_BENCH_CODEX_ALLOW_SOL?.trim() ?? ""
9230
+ )
9231
+ };
9232
+ }
9233
+ async function runWithinCodexCreditBudget(args) {
9234
+ if (!args.config) {
9235
+ return (await args.run()).value;
9236
+ }
9237
+ const previous = completionQueue;
9238
+ let release;
9239
+ completionQueue = new Promise((resolve) => {
9240
+ release = resolve;
9241
+ });
9242
+ await previous;
9243
+ const lockPath = `${args.config.ledgerPath}.lock`;
9244
+ let lock;
9245
+ let dispatchStarted = false;
9246
+ let accountingSettled = false;
9247
+ try {
9248
+ await mkdir5(path7.dirname(lockPath), { recursive: true, mode: 448 });
9249
+ lock = await acquireLedgerLock(lockPath);
9250
+ assertModelAllowed(args.model, args.config);
9251
+ const ledger = await readLedger(args.config);
9252
+ if (ledger.blockedReason) {
9253
+ throw new Error(
9254
+ `Codex credit ledger is blocked pending manual reconciliation: ${ledger.blockedReason}`
9255
+ );
9256
+ }
9257
+ const usableCredits = args.config.budgetCredits - args.config.reserveCredits;
9258
+ if (ledger.spentCredits >= usableCredits) {
9259
+ throw new Error(
9260
+ `Codex credit budget exhausted: ${ledger.spentCredits.toFixed(3)} spent; ${usableCredits.toFixed(3)} usable after the ${args.config.reserveCredits.toFixed(3)} safety reserve.`
9261
+ );
9262
+ }
9263
+ await writeLockState(lock, "in-flight");
9264
+ dispatchStarted = true;
9265
+ let result;
9266
+ try {
9267
+ result = await args.run();
9268
+ } catch (error) {
9269
+ if (error instanceof CodexCreditDispatchError) {
9270
+ await writeLockState(lock, "settled");
9271
+ accountingSettled = true;
9272
+ } else {
9273
+ const blockedLedger = {
9274
+ ...ledger,
9275
+ blockedReason: error instanceof CodexCreditAccountingError ? error.message : `Codex dispatch outcome is unknown after an unexpected error: ${safeErrorMessage(error)}`
9276
+ };
9277
+ await writeLedger(args.config.ledgerPath, blockedLedger);
9278
+ await writeLockState(lock, "settled");
9279
+ accountingSettled = true;
9280
+ }
9281
+ throw error;
9282
+ }
9283
+ const credits = calculateCodexCredits(args.model, result.usage);
9284
+ const nextSpent = ledger.spentCredits + credits;
9285
+ const nextLedger = {
9286
+ ...ledger,
9287
+ spentCredits: nextSpent,
9288
+ entries: [
9289
+ ...ledger.entries,
9290
+ {
9291
+ at: (/* @__PURE__ */ new Date()).toISOString(),
9292
+ model: args.model,
9293
+ credits,
9294
+ ...result.usage
9295
+ }
9296
+ ]
9297
+ };
9298
+ await writeLedger(args.config.ledgerPath, nextLedger);
9299
+ await writeLockState(lock, "settled");
9300
+ accountingSettled = true;
9301
+ args.onUsagePersisted?.(result.usage);
9302
+ if (nextSpent > args.config.budgetCredits) {
9303
+ throw new Error(
9304
+ `Codex credit budget exceeded by completed call: ${nextSpent.toFixed(3)} > ${args.config.budgetCredits.toFixed(3)} credits. Usage was persisted; stop the benchmark immediately.`
9305
+ );
9306
+ }
9307
+ return result.value;
9308
+ } finally {
9309
+ try {
9310
+ if (lock) {
9311
+ try {
9312
+ await lock.close();
9313
+ } finally {
9314
+ if (!dispatchStarted || accountingSettled) {
9315
+ await removeOwnedLedgerLock(lockPath);
9316
+ }
9317
+ }
9318
+ }
9319
+ } finally {
9320
+ release();
9321
+ }
9322
+ }
9323
+ }
9324
+ async function acquireLedgerLock(lockPath) {
9325
+ for (let attempt = 0; attempt < 2; attempt += 1) {
9326
+ try {
9327
+ await mkdir5(lockPath, { mode: 448 });
9328
+ } catch (error) {
9329
+ if (error.code !== "EEXIST") throw error;
9330
+ const owner = await readLockOwner(lockPath);
9331
+ if (!owner || isProcessAlive(owner.pid) || owner.phase === "in-flight") {
9332
+ throw new Error(
9333
+ `Codex credit ledger is locked${owner?.phase === "in-flight" ? " with unreconciled in-flight usage" : " by another benchmark process"} (${lockPath}); refusing credit spend.`
9334
+ );
9335
+ }
9336
+ await reclaimStaleLedgerLock(lockPath, owner);
9337
+ continue;
9338
+ }
9339
+ let createdLock;
9340
+ try {
9341
+ await mkdir5(lockHeldPath(lockPath));
9342
+ createdLock = await open(lockOwnerPath(lockPath), "wx", 384);
9343
+ await writeLockState(createdLock, "preflight");
9344
+ return createdLock;
9345
+ } catch (error) {
9346
+ await createdLock?.close().catch(() => void 0);
9347
+ await unlink3(lockOwnerPath(lockPath)).catch(() => void 0);
9348
+ await rmdir(lockHeldPath(lockPath)).catch(() => void 0);
9349
+ await rmdir(lockPath).catch(() => void 0);
9350
+ throw error;
9351
+ }
9352
+ }
9353
+ throw new Error(`Unable to acquire Codex credit ledger lock (${lockPath})`);
9354
+ }
9355
+ async function readLockOwner(lockPath) {
9356
+ try {
9357
+ const parsed = JSON.parse(await readFile6(lockOwnerPath(lockPath), "utf8"));
9358
+ if (!Number.isSafeInteger(parsed.pid) || parsed.pid <= 0 || parsed.phase !== "preflight" && parsed.phase !== "in-flight" && parsed.phase !== "settled") {
9359
+ return void 0;
9360
+ }
9361
+ return { pid: parsed.pid, phase: parsed.phase };
9362
+ } catch {
9363
+ return void 0;
9364
+ }
9365
+ }
9366
+ async function reclaimStaleLedgerLock(lockPath, expectedOwner) {
9367
+ try {
9368
+ await rmdir(lockHeldPath(lockPath));
9369
+ } catch (error) {
9370
+ throw new Error(
9371
+ `Codex credit ledger stale-lock reclamation is already claimed or incomplete (${lockPath}); refusing credit spend: ${safeErrorMessage(error)}`
9372
+ );
9373
+ }
9374
+ const currentOwner = await readLockOwner(lockPath);
9375
+ if (!currentOwner || currentOwner.pid !== expectedOwner.pid || currentOwner.phase !== expectedOwner.phase || isProcessAlive(currentOwner.pid) || currentOwner.phase === "in-flight") {
9376
+ throw new Error(
9377
+ `Codex credit ledger owner changed during stale-lock reclamation (${lockPath}); refusing credit spend.`
9378
+ );
9379
+ }
9380
+ await unlink3(lockOwnerPath(lockPath));
9381
+ await rmdir(lockPath);
9382
+ }
9383
+ async function removeOwnedLedgerLock(lockPath) {
9384
+ await rmdir(lockHeldPath(lockPath));
9385
+ await unlink3(lockOwnerPath(lockPath));
9386
+ await rmdir(lockPath);
9387
+ }
9388
+ function lockOwnerPath(lockPath) {
9389
+ return path7.join(lockPath, "owner.json");
9390
+ }
9391
+ function lockHeldPath(lockPath) {
9392
+ return path7.join(lockPath, "held");
9393
+ }
9394
+ async function writeLockState(lock, phase) {
9395
+ const contents = `${JSON.stringify({
9396
+ pid: process.pid,
9397
+ phase,
9398
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
9399
+ })}
9400
+ `;
9401
+ await lock.truncate(0);
9402
+ await lock.write(contents, 0, "utf8");
9403
+ await lock.sync();
9404
+ }
9405
+ function isProcessAlive(pid) {
9406
+ try {
9407
+ process.kill(pid, 0);
9408
+ return true;
9409
+ } catch (error) {
9410
+ return error.code === "EPERM";
9411
+ }
9412
+ }
9413
+ function parseCodexJsonlUsage(output) {
9414
+ let usage;
9415
+ for (const line of output.split(/\r?\n/)) {
9416
+ const trimmed = line.trim();
9417
+ if (!trimmed.startsWith("{")) continue;
9418
+ try {
9419
+ const event = JSON.parse(trimmed);
9420
+ if (event.type !== "turn.completed" || !event.usage) continue;
9421
+ const inputTokens = readCounter(event.usage.input_tokens);
9422
+ const outputTokens = readCounter(event.usage.output_tokens);
9423
+ const cachedInputTokens = readOptionalCounter(
9424
+ event.usage.cached_input_tokens
9425
+ );
9426
+ const reasoningOutputTokens = readOptionalCounter(
9427
+ event.usage.reasoning_output_tokens
9428
+ );
9429
+ if (inputTokens !== void 0 && outputTokens !== void 0 && cachedInputTokens !== void 0 && reasoningOutputTokens !== void 0) {
9430
+ usage = {
9431
+ inputTokens,
9432
+ cachedInputTokens,
9433
+ outputTokens,
9434
+ reasoningOutputTokens
9435
+ };
9436
+ }
9437
+ } catch {
9438
+ }
9439
+ }
9440
+ return usage;
9441
+ }
9442
+ function calculateCodexCredits(model, usage) {
9443
+ const rate = resolveRate(model);
9444
+ const cached = Math.min(usage.inputTokens, usage.cachedInputTokens);
9445
+ const uncached = usage.inputTokens - cached;
9446
+ return (uncached * rate.input + cached * rate.cachedInput + usage.outputTokens * rate.output) / ONE_MILLION;
9447
+ }
9448
+ function resolveRate(model) {
9449
+ const match = CREDIT_RATES.find(([pattern]) => pattern.test(model));
9450
+ if (!match) {
9451
+ throw new Error(
9452
+ `No Codex credit rate is configured for model ${JSON.stringify(model)}; refusing to run under a bounded credit budget.`
9453
+ );
9454
+ }
9455
+ return match[1];
9456
+ }
9457
+ function assertModelAllowed(model, config) {
9458
+ resolveRate(model);
9459
+ if (SOL_MODEL.test(model) && !config.allowSol) {
9460
+ throw new Error(
9461
+ "gpt-5.6-sol is disabled for bounded benchmark runs because it is the most expensive GPT-5.6 tier. Use gpt-5.6-terra or gpt-5.6-luna, or explicitly set REMNIC_BENCH_CODEX_ALLOW_SOL=1."
9462
+ );
9463
+ }
9464
+ }
9465
+ async function readLedger(config) {
9466
+ try {
9467
+ const parsed = JSON.parse(await readFile6(config.ledgerPath, "utf8"));
9468
+ if (parsed.schemaVersion !== 1 || parsed.budgetCredits !== config.budgetCredits || parsed.reserveCredits !== config.reserveCredits || typeof parsed.spentCredits !== "number" || !Number.isFinite(parsed.spentCredits) || parsed.spentCredits < 0 || !Array.isArray(parsed.entries)) {
9469
+ throw new Error("ledger schema or budget does not match this run");
9470
+ }
9471
+ return parsed;
9472
+ } catch (error) {
9473
+ if (error.code !== "ENOENT") {
9474
+ throw new Error(`Invalid Codex credit ledger at ${config.ledgerPath}: ${String(error)}`);
9475
+ }
9476
+ return {
9477
+ schemaVersion: 1,
9478
+ budgetCredits: config.budgetCredits,
9479
+ reserveCredits: config.reserveCredits,
9480
+ spentCredits: 0,
9481
+ entries: []
9482
+ };
9483
+ }
9484
+ }
9485
+ async function writeLedger(filePath, ledger) {
9486
+ await mkdir5(path7.dirname(filePath), { recursive: true, mode: 448 });
9487
+ const tempPath = `${filePath}.${process.pid}.tmp`;
9488
+ await writeFile5(tempPath, `${JSON.stringify(ledger, null, 2)}
9489
+ `, {
9490
+ encoding: "utf8",
9491
+ mode: 384
9492
+ });
9493
+ await rename2(tempPath, filePath);
9494
+ }
9495
+ function readCounter(value) {
9496
+ return Number.isSafeInteger(value) && value >= 0 ? value : void 0;
9497
+ }
9498
+ function readOptionalCounter(value) {
9499
+ return value === void 0 ? 0 : readCounter(value);
9500
+ }
9501
+ function safeErrorMessage(error) {
9502
+ return error instanceof Error ? error.message : String(error);
9503
+ }
9504
+ function expandHomeRelativePath2(value) {
9505
+ if (value === "~") return os4.homedir();
9506
+ if (value.startsWith("~/") || value.startsWith("~\\")) {
9507
+ return path7.join(os4.homedir(), value.slice(2));
9508
+ }
9509
+ return value;
9510
+ }
9511
+ function parsePositiveNumber(value, name) {
9512
+ const parsed = Number(value);
9513
+ if (!Number.isFinite(parsed) || parsed <= 0) {
9514
+ throw new Error(`${name} must be a finite number greater than zero`);
9515
+ }
9516
+ return parsed;
9517
+ }
9518
+ function parseNonNegativeNumber(value, name) {
9519
+ const parsed = Number(value);
9520
+ if (!Number.isFinite(parsed) || parsed < 0) {
9521
+ throw new Error(`${name} must be a finite non-negative number`);
9522
+ }
9523
+ return parsed;
9524
+ }
9525
+
9526
+ // src/providers/codex-cli.ts
8978
9527
  var DEFAULT_REASONING_EFFORT = "xhigh";
8979
- var DEFAULT_SERVICE_TIER = "fast";
9528
+ var DEFAULT_SERVICE_TIER = "default";
8980
9529
  var CODEX_CLI_STDIO_LIMIT = 64e3;
8981
9530
  var CODEX_CLI_PARENT_SIGNALS = [
8982
9531
  "SIGHUP",
@@ -8987,12 +9536,8 @@ var CODEX_CLI_FORCED_PARENT_EXIT_MS = 1e3;
8987
9536
  var CODEX_CLI_DIAGNOSTICS_DIR_ENV = "REMNIC_BENCH_CODEX_CLI_DIAGNOSTICS_DIR";
8988
9537
  var CODEX_CLI_DIAGNOSTICS_MODE_ENV = "REMNIC_BENCH_CODEX_CLI_DIAGNOSTICS_MODE";
8989
9538
  var CODEX_CLI_EXECUTABLE_ENV = "REMNIC_BENCH_CODEX_CLI_EXECUTABLE";
8990
- var CODEX_CLI_TRANSPORT_ENV = "REMNIC_BENCH_CODEX_CLI_TRANSPORT";
8991
9539
  var CODEX_CLI_VERSION_TIMEOUT_MS = 5e3;
8992
- var CODEX_CLI_HEALTH_CACHE_TTL_MS = 3e4;
8993
- var OPENAI_API_KEY_ENV = "OPENAI_API_KEY";
8994
- var OPENAI_BASE_URL_ENV = "OPENAI_BASE_URL";
8995
- var OPENAI_RESPONSES_BASE_URL = "https://api.openai.com/v1";
9540
+ var CODEX_CLI_PRE_START_ABORT_MESSAGE = "Codex CLI aborted before start.";
8996
9541
  var CODEX_CLI_RUNTIME_ENV_ALLOWLIST = /* @__PURE__ */ new Set([
8997
9542
  "ALL_PROXY",
8998
9543
  "APPDATA",
@@ -9010,9 +9555,6 @@ var CODEX_CLI_RUNTIME_ENV_ALLOWLIST = /* @__PURE__ */ new Set([
9010
9555
  "NODE_EXTRA_CA_CERTS",
9011
9556
  "NO_PROXY",
9012
9557
  "NUMBER_OF_PROCESSORS",
9013
- OPENAI_BASE_URL_ENV,
9014
- "OPENAI_ORGANIZATION",
9015
- "OPENAI_PROJECT",
9016
9558
  "OS",
9017
9559
  "PATH",
9018
9560
  "PATHEXT",
@@ -9040,7 +9582,7 @@ var CODEX_CLI_RUNTIME_ENV_ALLOWLIST = /* @__PURE__ */ new Set([
9040
9582
  ]);
9041
9583
  var activeCodexCliChildPids = /* @__PURE__ */ new Set();
9042
9584
  var codexCliParentCleanupInstalled = false;
9043
- var codexCliHealthCache = /* @__PURE__ */ new Map();
9585
+ var codexCliLoginStatusCache = /* @__PURE__ */ new Map();
9044
9586
  var CodexCliProvider = class {
9045
9587
  provider = "codex-cli";
9046
9588
  id;
@@ -9048,7 +9590,8 @@ var CodexCliProvider = class {
9048
9590
  config;
9049
9591
  runCodexCli;
9050
9592
  runCodexVersion;
9051
- shouldProbeCliHealth;
9593
+ runCodexLoginStatus;
9594
+ requiresExactUsage;
9052
9595
  usage = {
9053
9596
  inputTokens: 0,
9054
9597
  outputTokens: 0,
@@ -9058,23 +9601,28 @@ var CodexCliProvider = class {
9058
9601
  this.config = config;
9059
9602
  this.runCodexCli = deps.runCodexCli ?? runCodexCliCommand;
9060
9603
  this.runCodexVersion = deps.runCodexVersion ?? runCodexVersionCommand;
9061
- this.shouldProbeCliHealth = deps.runCodexCli === void 0;
9604
+ this.runCodexLoginStatus = deps.runCodexLoginStatus ?? runCodexLoginStatusCommand;
9605
+ this.requiresExactUsage = deps.runCodexCli === void 0;
9062
9606
  this.id = `codex-cli:${config.model}`;
9063
9607
  this.name = config.model;
9064
9608
  }
9065
9609
  async complete(prompt, opts = {}) {
9610
+ if (opts.signal?.aborted) {
9611
+ throw codexCliAbortError(opts.signal);
9612
+ }
9066
9613
  const startedAt = performance.now();
9067
- if (await this.shouldUseResponsesFallback()) {
9068
- return this.completeViaResponsesApi(prompt, opts, startedAt);
9614
+ const creditBudget = resolveCodexCreditBudgetConfig();
9615
+ if (creditBudget) {
9616
+ await this.assertChatGptCreditAuth();
9069
9617
  }
9070
9618
  const maxAttempts = normalizeCodexCliMaxAttempts(
9071
- this.config.retryOptions?.maxAttempts
9619
+ creditBudget ? 1 : this.config.retryOptions?.maxAttempts
9072
9620
  );
9073
9621
  let lastError;
9074
9622
  for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
9075
- const tempDir = await mkdtemp3(path7.join(os4.tmpdir(), "remnic-codex-cli-"));
9076
- const workspacePath = path7.join(tempDir, "workspace");
9077
- const outputPath = path7.join(tempDir, "last-message.txt");
9623
+ const tempDir = await mkdtemp3(path8.join(os5.tmpdir(), "remnic-codex-cli-"));
9624
+ const workspacePath = path8.join(tempDir, "workspace");
9625
+ const outputPath = path8.join(tempDir, "last-message.txt");
9078
9626
  let diagnostics;
9079
9627
  let diagnosticsFinished = false;
9080
9628
  const finishDiagnostics = async (outcome) => {
@@ -9085,7 +9633,7 @@ var CodexCliProvider = class {
9085
9633
  await finishCodexCliDiagnostics(diagnostics, startedAt, outcome);
9086
9634
  };
9087
9635
  try {
9088
- await mkdir5(workspacePath, { recursive: true });
9636
+ await mkdir6(workspacePath, { recursive: true });
9089
9637
  const request = this.buildRunRequest(prompt, opts, workspacePath, outputPath);
9090
9638
  diagnostics = await startCodexCliDiagnostics({
9091
9639
  config: this.config,
@@ -9094,12 +9642,48 @@ var CodexCliProvider = class {
9094
9642
  serviceTier: DEFAULT_SERVICE_TIER,
9095
9643
  retry: { attempt, maxAttempts }
9096
9644
  });
9097
- const result = await this.runCodexCli(request);
9645
+ const result = creditBudget ? await runWithinCodexCreditBudget({
9646
+ config: creditBudget,
9647
+ model: this.config.model,
9648
+ onUsagePersisted: (usage) => {
9649
+ this.recordUsage(usage.inputTokens, usage.outputTokens);
9650
+ },
9651
+ run: async () => {
9652
+ if (opts.signal?.aborted) {
9653
+ throw codexCliPreStartAbortError(opts.signal);
9654
+ }
9655
+ let value;
9656
+ try {
9657
+ value = await this.runCodexCli(request);
9658
+ } catch (error) {
9659
+ if (error instanceof CodexCreditDispatchError || error instanceof CodexCreditAccountingError) {
9660
+ throw error;
9661
+ }
9662
+ throw new CodexCreditAccountingError(
9663
+ `Codex CLI failed after dispatch; account balance must be reconciled before resuming: ${safeErrorMessage2(error)}`
9664
+ );
9665
+ }
9666
+ const usage = parseCodexJsonlUsage(
9667
+ `${value.stdout}
9668
+ ${value.stderr}`
9669
+ );
9670
+ if (!usage) {
9671
+ throw new CodexCreditAccountingError(
9672
+ `Codex CLI exited ${value.status ?? "without a status"} without exact turn.completed usage; account balance must be reconciled before resuming.`
9673
+ );
9674
+ }
9675
+ return { value, usage };
9676
+ }
9677
+ }) : await this.runCodexCli(request);
9678
+ const exactUsage = parseCodexJsonlUsage(
9679
+ `${result.stdout}
9680
+ ${result.stderr}`
9681
+ );
9682
+ if (!creditBudget && exactUsage) {
9683
+ this.recordUsage(exactUsage.inputTokens, exactUsage.outputTokens);
9684
+ }
9098
9685
  if (result.status !== 0) {
9099
- const exitLabel = result.signal ? `signal ${result.signal}` : `exit ${result.status ?? "unknown"}`;
9100
- const error = new Error(
9101
- `Codex CLI completion failed (${exitLabel}): ${summarizeProcessOutput2(result.stderr, result.stdout)}`
9102
- );
9686
+ const error = codexCliResultError(result);
9103
9687
  if (attempt < maxAttempts && isRetryableCodexCliResult(result)) {
9104
9688
  lastError = error;
9105
9689
  await finishDiagnostics({
@@ -9126,12 +9710,14 @@ var CodexCliProvider = class {
9126
9710
  throw error;
9127
9711
  }
9128
9712
  await finishDiagnostics({ result });
9129
- const tokens = parseCodexTokenUsage(
9130
- `${result.stderr}
9131
- ${result.stdout}`,
9132
- text
9133
- );
9134
- this.recordUsage(tokens.input, tokens.output);
9713
+ const nativeUsage = exactUsage ?? (this.requiresExactUsage ? requireCodexJsonlUsage(result) : readCodexUsage(result, text));
9714
+ const tokens = {
9715
+ input: nativeUsage.inputTokens,
9716
+ output: nativeUsage.outputTokens
9717
+ };
9718
+ if (!creditBudget && !exactUsage) {
9719
+ this.recordUsage(tokens.input, tokens.output);
9720
+ }
9135
9721
  return {
9136
9722
  text,
9137
9723
  tokens,
@@ -9139,15 +9725,93 @@ ${result.stdout}`,
9139
9725
  model: this.config.model
9140
9726
  };
9141
9727
  } catch (error) {
9142
- lastError = error;
9143
- await finishDiagnostics({ error });
9144
- throw error;
9728
+ const surfacedError = unwrapCodexCliPreStartAbort(error);
9729
+ lastError = surfacedError;
9730
+ await finishDiagnostics({ error: surfacedError });
9731
+ throw surfacedError;
9145
9732
  } finally {
9146
9733
  await rm3(tempDir, { force: true, recursive: true });
9147
9734
  }
9148
9735
  }
9149
9736
  throw lastError instanceof Error ? lastError : new Error(String(lastError));
9150
9737
  }
9738
+ async judge(request) {
9739
+ const startedAt = performance.now();
9740
+ try {
9741
+ const completion = await this.complete(request.input, {
9742
+ systemPrompt: buildCodexStructuredJudgePrompt(request.rubric),
9743
+ temperature: 0,
9744
+ maxTokens: request.maxTokens ?? 256,
9745
+ signal: request.signal
9746
+ });
9747
+ const telemetry = {
9748
+ model: completion.model,
9749
+ rubricVersion: request.rubricVersion,
9750
+ inputTokens: completion.tokens.input,
9751
+ outputTokens: completion.tokens.output,
9752
+ latencyMs: completion.latencyMs
9753
+ };
9754
+ const verdict = parseStructuredJudgeVerdict(completion.text);
9755
+ if (!verdict) {
9756
+ return {
9757
+ ok: false,
9758
+ error: {
9759
+ code: "malformed_verdict",
9760
+ message: "Codex CLI returned a verdict that failed schema validation.",
9761
+ retryable: false
9762
+ },
9763
+ telemetry: { ...telemetry, errorCode: "malformed_verdict" }
9764
+ };
9765
+ }
9766
+ return { ok: true, verdict, telemetry };
9767
+ } catch (error) {
9768
+ const aborted = isCodexStructuredJudgeAbort(error, request.signal);
9769
+ const errorCode = aborted ? "aborted" : "transport_error";
9770
+ return {
9771
+ ok: false,
9772
+ error: {
9773
+ code: errorCode,
9774
+ message: aborted ? "Codex CLI judging was aborted by the caller." : `Codex CLI judging failed (${structuredJudgeErrorName(error)}).`,
9775
+ retryable: false
9776
+ },
9777
+ telemetry: {
9778
+ model: this.config.model,
9779
+ rubricVersion: request.rubricVersion,
9780
+ inputTokens: 0,
9781
+ outputTokens: 0,
9782
+ latencyMs: Math.round(performance.now() - startedAt),
9783
+ errorCode
9784
+ }
9785
+ };
9786
+ }
9787
+ }
9788
+ async evaluateAssistantRubric(request) {
9789
+ const rubricVersion = `sealed:${request.rubricId}`;
9790
+ const completion = await this.complete(request.user, {
9791
+ systemPrompt: buildCodexAssistantRubricPrompt(request.system),
9792
+ temperature: 0,
9793
+ maxTokens: 512
9794
+ });
9795
+ if (isValidAssistantRubric(completion.text)) {
9796
+ return completion.text;
9797
+ }
9798
+ throw new StructuredJudgeError({
9799
+ ok: false,
9800
+ error: {
9801
+ code: "malformed_verdict",
9802
+ message: "Codex CLI returned an invalid sealed assistant-rubric verdict.",
9803
+ retryable: false
9804
+ },
9805
+ telemetry: {
9806
+ model: completion.model,
9807
+ rubricVersion,
9808
+ inputTokens: completion.tokens.input,
9809
+ outputTokens: completion.tokens.output,
9810
+ latencyMs: completion.latencyMs,
9811
+ errorCode: "malformed_verdict"
9812
+ }
9813
+ });
9814
+ }
9151
9815
  async discover() {
9152
9816
  const version = await this.runCodexVersion(
9153
9817
  resolveCodexCliExecutable(this.config),
@@ -9177,6 +9841,26 @@ ${result.stdout}`,
9177
9841
  totalTokens: 0
9178
9842
  };
9179
9843
  }
9844
+ async assertChatGptCreditAuth() {
9845
+ const executable = resolveCodexCliExecutable(this.config);
9846
+ const env = buildIsolatedCodexEnv();
9847
+ const cacheKey = `${executable}\0${env.CODEX_HOME ?? env.HOME ?? ""}`;
9848
+ let check = codexCliLoginStatusCache.get(cacheKey);
9849
+ if (!check) {
9850
+ check = this.runCodexLoginStatus(executable, env).then((result) => {
9851
+ const output = `${result.stdout}
9852
+ ${result.stderr}`.trim();
9853
+ if (result.status !== 0 || !/logged in using chatgpt/i.test(output)) {
9854
+ throw new Error(
9855
+ `Bounded Codex credit runs require ChatGPT-backed Codex CLI authentication; \`codex login status\` reported: ${output || `exit ${result.status ?? "unknown"}`}`
9856
+ );
9857
+ }
9858
+ });
9859
+ codexCliLoginStatusCache.set(cacheKey, check);
9860
+ check.catch(() => codexCliLoginStatusCache.delete(cacheKey));
9861
+ }
9862
+ await check;
9863
+ }
9180
9864
  recordUsage(inputTokens, outputTokens) {
9181
9865
  this.usage = {
9182
9866
  inputTokens: this.usage.inputTokens + inputTokens,
@@ -9184,126 +9868,57 @@ ${result.stdout}`,
9184
9868
  totalTokens: this.usage.totalTokens + inputTokens + outputTokens
9185
9869
  };
9186
9870
  }
9187
- async shouldUseResponsesFallback() {
9188
- const transport = process.env[CODEX_CLI_TRANSPORT_ENV]?.trim().toLowerCase();
9189
- if (transport === "cli") {
9190
- return false;
9191
- }
9192
- if (transport === "responses") {
9193
- return true;
9194
- }
9195
- if (!this.shouldProbeCliHealth || this.resolveOpenAiApiKey().length === 0) {
9196
- return false;
9197
- }
9198
- return !await this.isCliHealthy();
9199
- }
9200
- async isCliHealthy() {
9201
- const executable = resolveCodexCliExecutable(this.config);
9202
- const env = buildIsolatedCodexEnv(this.config.apiKey);
9203
- if (this.runCodexVersion !== runCodexVersionCommand) {
9204
- return this.probeCliHealth(executable, env);
9205
- }
9206
- const cacheKey = `${executable}\0${env.PATH ?? ""}`;
9207
- const cached = codexCliHealthCache.get(cacheKey);
9208
- if (cached && Date.now() - cached.checkedAt < CODEX_CLI_HEALTH_CACHE_TTL_MS) {
9209
- return cached.promise;
9210
- }
9211
- if (cached) {
9212
- codexCliHealthCache.delete(cacheKey);
9213
- }
9214
- const promise = this.probeCliHealth(executable, env).then((healthy) => {
9215
- if (!healthy) {
9216
- codexCliHealthCache.delete(cacheKey);
9217
- }
9218
- return healthy;
9219
- });
9220
- codexCliHealthCache.set(cacheKey, { checkedAt: Date.now(), promise });
9221
- return promise;
9222
- }
9223
- async probeCliHealth(executable, env) {
9224
- try {
9225
- const version = await this.runCodexVersion(executable, env);
9226
- return version.status === 0;
9227
- } catch {
9228
- return false;
9229
- }
9230
- }
9231
- resolveOpenAiApiKey() {
9232
- return (this.config.apiKey ?? process.env[OPENAI_API_KEY_ENV] ?? "").trim();
9233
- }
9234
- async completeViaResponsesApi(prompt, opts, startedAt) {
9235
- const apiKey = this.resolveOpenAiApiKey();
9236
- if (apiKey.length === 0) {
9237
- throw new Error(
9238
- `Codex CLI fallback requires ${OPENAI_API_KEY_ENV} or codex-cli apiKey.`
9239
- );
9240
- }
9241
- const serviceTier = responsesApiServiceTier(DEFAULT_SERVICE_TIER);
9242
- const body = {
9243
- model: this.config.model,
9244
- instructions: buildResponsesInstructions(opts.systemPrompt),
9245
- input: prompt,
9246
- reasoning: {
9247
- effort: this.config.reasoningEffort ?? DEFAULT_REASONING_EFFORT
9248
- },
9249
- ...serviceTier ? { service_tier: serviceTier } : {},
9250
- max_output_tokens: Math.max(1, Math.floor(opts.maxTokens ?? 1024)),
9251
- store: false
9252
- };
9253
- const response = await retryFetch(
9254
- this.responsesApiUrl(),
9255
- {
9256
- method: "POST",
9257
- headers: {
9258
- "content-type": "application/json",
9259
- authorization: `Bearer ${apiKey}`
9260
- },
9261
- signal: opts.signal,
9262
- body: JSON.stringify(body)
9263
- },
9264
- this.config.retryOptions
9265
- );
9266
- if (!response.ok) {
9267
- throw new Error(
9268
- `Codex CLI Responses API fallback failed: ${response.status} ${response.statusText}${await readResponseErrorBody(response)}`
9269
- );
9270
- }
9271
- const payload = await response.json();
9272
- const text = extractResponsesOutputText(payload).trim();
9273
- if (text.length === 0) {
9274
- throw new Error("Codex CLI Responses API fallback returned no text.");
9275
- }
9276
- const inputTokens = payload.usage?.input_tokens ?? 0;
9277
- const outputTokens = payload.usage?.output_tokens ?? 0;
9278
- this.recordUsage(inputTokens, outputTokens);
9279
- return {
9280
- text,
9281
- tokens: { input: inputTokens, output: outputTokens },
9282
- latencyMs: Math.round(performance.now() - startedAt),
9283
- model: payload.model ?? this.config.model
9284
- };
9285
- }
9286
- responsesApiUrl() {
9287
- const baseUrl = (this.config.baseUrl ?? OPENAI_RESPONSES_BASE_URL).replace(
9288
- /\/$/,
9289
- ""
9290
- );
9291
- return baseUrl.endsWith("/v1") ? `${baseUrl}/responses` : `${baseUrl}/v1/responses`;
9292
- }
9293
9871
  buildRunRequest(prompt, opts, workspacePath, outputPath) {
9294
9872
  const reasoningEffort = this.config.reasoningEffort ?? DEFAULT_REASONING_EFFORT;
9295
9873
  const args = [
9296
9874
  "exec",
9875
+ "--strict-config",
9297
9876
  "--model",
9298
9877
  this.config.model,
9299
9878
  "--config",
9300
9879
  `model_reasoning_effort=${tomlString(reasoningEffort)}`,
9301
9880
  "--config",
9302
- `service_tier=${tomlString(DEFAULT_SERVICE_TIER)}`,
9303
- "--config",
9304
9881
  'approval_policy="never"',
9882
+ "--config",
9883
+ 'web_search="disabled"',
9884
+ "--disable",
9885
+ "hooks",
9886
+ "--disable",
9887
+ "shell_tool",
9888
+ "--disable",
9889
+ "unified_exec",
9890
+ "--disable",
9891
+ "apps",
9892
+ "--disable",
9893
+ "plugins",
9894
+ "--disable",
9895
+ "remote_plugin",
9305
9896
  "--disable",
9306
- "codex_hooks",
9897
+ "multi_agent",
9898
+ "--disable",
9899
+ "browser_use",
9900
+ "--disable",
9901
+ "browser_use_external",
9902
+ "--disable",
9903
+ "browser_use_full_cdp_access",
9904
+ "--disable",
9905
+ "computer_use",
9906
+ "--disable",
9907
+ "image_generation",
9908
+ "--disable",
9909
+ "in_app_browser",
9910
+ "--disable",
9911
+ "goals",
9912
+ "--disable",
9913
+ "memories",
9914
+ "--disable",
9915
+ "chronicle",
9916
+ "--disable",
9917
+ "tool_suggest",
9918
+ "--disable",
9919
+ "workspace_dependencies",
9920
+ "--disable",
9921
+ "shell_snapshot",
9307
9922
  "--ephemeral",
9308
9923
  "--ignore-user-config",
9309
9924
  "--ignore-rules",
@@ -9312,6 +9927,7 @@ ${result.stdout}`,
9312
9927
  "--cd",
9313
9928
  workspacePath,
9314
9929
  "--skip-git-repo-check",
9930
+ "--json",
9315
9931
  "--output-last-message",
9316
9932
  outputPath,
9317
9933
  "-"
@@ -9324,50 +9940,10 @@ ${result.stdout}`,
9324
9940
  workspacePath,
9325
9941
  timeoutMs: this.config.retryOptions?.timeoutMs,
9326
9942
  signal: opts.signal,
9327
- env: buildIsolatedCodexEnv(this.config.apiKey, this.config.baseUrl)
9943
+ env: buildIsolatedCodexEnv()
9328
9944
  };
9329
9945
  }
9330
9946
  };
9331
- function responsesApiServiceTier(serviceTier) {
9332
- if (serviceTier === "auto" || serviceTier === "default" || serviceTier === "flex" || serviceTier === "scale" || serviceTier === "priority") {
9333
- return serviceTier;
9334
- }
9335
- return void 0;
9336
- }
9337
- function buildResponsesInstructions(systemPrompt) {
9338
- return [
9339
- "You are acting as a benchmark LLM completion endpoint, not as a coding agent.",
9340
- "Use only the user input and the benchmark system instructions.",
9341
- "Do not inspect files, run commands, browse, use tools, or use persisted memory.",
9342
- "Return only the final answer text. If the request asks for JSON, return raw JSON only.",
9343
- ...systemPrompt?.trim() ? ["", systemPrompt.trim()] : []
9344
- ].join("\n");
9345
- }
9346
- async function readResponseErrorBody(response) {
9347
- try {
9348
- const body = await response.text();
9349
- return body.trim().length > 0 ? ` \u2014 ${body.slice(0, 1e3)}` : "";
9350
- } catch {
9351
- return "";
9352
- }
9353
- }
9354
- function extractResponsesOutputText(payload) {
9355
- if (typeof payload.output_text === "string" && payload.output_text.length > 0) {
9356
- return payload.output_text;
9357
- }
9358
- const parts = [];
9359
- for (const item of payload.output ?? []) {
9360
- if (typeof item.text === "string" && item.text.length > 0) {
9361
- parts.push(item.text);
9362
- }
9363
- for (const content of item.content ?? []) {
9364
- if (typeof content.text === "string" && content.text.length > 0 && (content.type === void 0 || content.type.endsWith("_text"))) {
9365
- parts.push(content.text);
9366
- }
9367
- }
9368
- }
9369
- return parts.join("\n");
9370
- }
9371
9947
  function runCodexVersionCommand(executable, env) {
9372
9948
  return new Promise((resolve, reject) => {
9373
9949
  const child = spawn2(executable, ["--version"], {
@@ -9425,6 +10001,58 @@ Codex CLI --version timed out after ${CODEX_CLI_VERSION_TIMEOUT_MS}ms.`
9425
10001
  });
9426
10002
  });
9427
10003
  }
10004
+ function runCodexLoginStatusCommand(executable, env) {
10005
+ return new Promise((resolve, reject) => {
10006
+ const child = spawn2(executable, ["login", "status"], {
10007
+ env,
10008
+ stdio: ["ignore", "pipe", "pipe"],
10009
+ detached: process.platform !== "win32",
10010
+ windowsHide: true
10011
+ });
10012
+ let stdout = "";
10013
+ let stderr = "";
10014
+ let killTimeout;
10015
+ const terminate = (signal) => {
10016
+ if (child.pid && process.platform !== "win32") {
10017
+ try {
10018
+ process.kill(-child.pid, signal);
10019
+ return;
10020
+ } catch {
10021
+ }
10022
+ }
10023
+ child.kill(signal);
10024
+ };
10025
+ const timeout = setTimeout(() => {
10026
+ stderr = appendBounded2(
10027
+ stderr,
10028
+ `
10029
+ Codex CLI login status timed out after ${CODEX_CLI_VERSION_TIMEOUT_MS}ms.`
10030
+ );
10031
+ terminate("SIGTERM");
10032
+ killTimeout = setTimeout(() => terminate("SIGKILL"), 1e3);
10033
+ killTimeout.unref();
10034
+ }, CODEX_CLI_VERSION_TIMEOUT_MS);
10035
+ timeout.unref();
10036
+ child.stdout?.setEncoding("utf8");
10037
+ child.stderr?.setEncoding("utf8");
10038
+ child.stdout?.on("data", (chunk) => {
10039
+ stdout = appendBounded2(stdout, chunk);
10040
+ });
10041
+ child.stderr?.on("data", (chunk) => {
10042
+ stderr = appendBounded2(stderr, chunk);
10043
+ });
10044
+ child.on("error", (error) => {
10045
+ clearTimeout(timeout);
10046
+ if (killTimeout) clearTimeout(killTimeout);
10047
+ reject(error);
10048
+ });
10049
+ child.on("close", (status) => {
10050
+ clearTimeout(timeout);
10051
+ if (killTimeout) clearTimeout(killTimeout);
10052
+ resolve({ status, stdout, stderr });
10053
+ });
10054
+ });
10055
+ }
9428
10056
  function resolveCodexCliExecutable(config) {
9429
10057
  const configured = config.executable ?? process.env[CODEX_CLI_EXECUTABLE_ENV];
9430
10058
  if (configured === void 0) {
@@ -9436,7 +10064,7 @@ function resolveCodexCliExecutable(config) {
9436
10064
  `${CODEX_CLI_EXECUTABLE_ENV} / codex-cli executable must not be empty`
9437
10065
  );
9438
10066
  }
9439
- return expandHomeRelativePath2(trimmed);
10067
+ return expandHomeRelativePath3(trimmed);
9440
10068
  }
9441
10069
  function buildCodexCompletionPrompt(userPrompt, systemPrompt) {
9442
10070
  const payload = {
@@ -9454,21 +10082,13 @@ function buildCodexCompletionPrompt(userPrompt, systemPrompt) {
9454
10082
  JSON.stringify(payload, null, 2)
9455
10083
  ].join("\n");
9456
10084
  }
9457
- function buildIsolatedCodexEnv(apiKey, baseUrl) {
10085
+ function buildIsolatedCodexEnv() {
9458
10086
  const env = {};
9459
10087
  for (const [key, value] of Object.entries(process.env)) {
9460
10088
  if (value !== void 0 && isAllowedCodexRuntimeEnvKey(key)) {
9461
10089
  env[key] = value;
9462
10090
  }
9463
10091
  }
9464
- const resolvedApiKey = (apiKey ?? process.env[OPENAI_API_KEY_ENV] ?? "").trim();
9465
- if (resolvedApiKey.length > 0) {
9466
- env[OPENAI_API_KEY_ENV] = resolvedApiKey;
9467
- }
9468
- const resolvedBaseUrl = (baseUrl ?? process.env[OPENAI_BASE_URL_ENV] ?? "").trim();
9469
- if (resolvedBaseUrl.length > 0) {
9470
- env[OPENAI_BASE_URL_ENV] = resolvedBaseUrl;
9471
- }
9472
10092
  return env;
9473
10093
  }
9474
10094
  function isAllowedCodexRuntimeEnvKey(key) {
@@ -9481,7 +10101,7 @@ async function startCodexCliDiagnostics(args) {
9481
10101
  return void 0;
9482
10102
  }
9483
10103
  try {
9484
- await mkdir5(diagnosticsDir, { recursive: true, mode: 448 });
10104
+ await mkdir6(diagnosticsDir, { recursive: true, mode: 448 });
9485
10105
  const id = `${Date.now()}-${process.pid}-${randomUUID()}`;
9486
10106
  const promptStats = inspectCodexCompletionPrompt(args.request.input);
9487
10107
  const mode = resolveCodexCliDiagnosticsMode(args.config);
@@ -9494,10 +10114,10 @@ async function startCodexCliDiagnostics(args) {
9494
10114
  model: args.config.model,
9495
10115
  reasoningEffort: args.reasoningEffort,
9496
10116
  serviceTier: args.serviceTier,
9497
- executable: path7.basename(args.request.executable),
10117
+ executable: path8.basename(args.request.executable),
9498
10118
  ...args.request.timeoutMs ? { timeoutMs: args.request.timeoutMs } : {},
9499
- workspaceBasename: path7.basename(args.request.workspacePath),
9500
- outputBasename: path7.basename(args.request.outputPath),
10119
+ workspaceBasename: path8.basename(args.request.workspacePath),
10120
+ outputBasename: path8.basename(args.request.outputPath),
9501
10121
  prompt: promptStats,
9502
10122
  command: {
9503
10123
  args: redactCodexCliArgs(args.request.args)
@@ -9505,7 +10125,7 @@ async function startCodexCliDiagnostics(args) {
9505
10125
  retry: args.retry,
9506
10126
  ...mode === "full" ? { fullPrompt: args.request.input } : {}
9507
10127
  };
9508
- const filePath = path7.join(diagnosticsDir, `${id}.json`);
10128
+ const filePath = path8.join(diagnosticsDir, `${id}.json`);
9509
10129
  await writeCodexCliDiagnosticRecord(filePath, record);
9510
10130
  return { path: filePath, record };
9511
10131
  } catch {
@@ -9548,7 +10168,7 @@ async function finishCodexCliDiagnostics(handle, startedAt, outcome) {
9548
10168
  }
9549
10169
  }
9550
10170
  async function writeCodexCliDiagnosticRecord(filePath, record) {
9551
- await writeFile5(filePath, `${JSON.stringify(record, null, 2)}
10171
+ await writeFile6(filePath, `${JSON.stringify(record, null, 2)}
9552
10172
  `, {
9553
10173
  encoding: "utf8",
9554
10174
  mode: 384
@@ -9557,14 +10177,14 @@ async function writeCodexCliDiagnosticRecord(filePath, record) {
9557
10177
  function resolveCodexCliDiagnosticsDir(config) {
9558
10178
  const dir = config.diagnosticsDir ?? process.env[CODEX_CLI_DIAGNOSTICS_DIR_ENV];
9559
10179
  const trimmed = typeof dir === "string" ? dir.trim() : "";
9560
- return trimmed.length > 0 ? path7.resolve(expandHomeRelativePath2(trimmed)) : void 0;
10180
+ return trimmed.length > 0 ? path8.resolve(expandHomeRelativePath3(trimmed)) : void 0;
9561
10181
  }
9562
- function expandHomeRelativePath2(value) {
10182
+ function expandHomeRelativePath3(value) {
9563
10183
  if (value === "~") {
9564
- return os4.homedir();
10184
+ return os5.homedir();
9565
10185
  }
9566
10186
  if (value.startsWith("~/") || value.startsWith("~\\")) {
9567
- return path7.join(os4.homedir(), value.slice(2));
10187
+ return path8.join(os5.homedir(), value.slice(2));
9568
10188
  }
9569
10189
  return value;
9570
10190
  }
@@ -9614,13 +10234,7 @@ function redactCodexCliArgs(args) {
9614
10234
  function runCodexCliCommand(request) {
9615
10235
  return new Promise((resolve, reject) => {
9616
10236
  if (request.signal?.aborted) {
9617
- resolve({
9618
- status: 124,
9619
- signal: null,
9620
- stdout: "",
9621
- stderr: "Codex CLI aborted before start.",
9622
- outputText: ""
9623
- });
10237
+ reject(codexCliPreStartAbortError(request.signal));
9624
10238
  return;
9625
10239
  }
9626
10240
  const child = spawn2(request.executable, request.args, {
@@ -9704,7 +10318,15 @@ Codex CLI stdin error: ${error.code ?? error.message}`
9704
10318
  unregisterActiveCodexCliChild(child.pid);
9705
10319
  }
9706
10320
  request.signal?.removeEventListener("abort", onAbort);
9707
- reject(error);
10321
+ reject(
10322
+ child.pid ? new Error(
10323
+ `Codex CLI failed after its process started: ${safeErrorMessage2(error)}`,
10324
+ { cause: error }
10325
+ ) : new CodexCreditDispatchError(
10326
+ `Codex CLI could not start: ${safeErrorMessage2(error)}`,
10327
+ { cause: error }
10328
+ )
10329
+ );
9708
10330
  });
9709
10331
  child.on("close", async (status, signal) => {
9710
10332
  if (timeout) {
@@ -9740,10 +10362,17 @@ Codex CLI timed out after ${request.timeoutMs}ms.`
9740
10362
  return;
9741
10363
  }
9742
10364
  try {
9743
- const outputText = await readCodexOutput(request.outputPath, stdout);
10365
+ const outputText = await readCodexOutput(request.outputPath, status);
9744
10366
  resolve({ status, signal, stdout, stderr, outputText });
9745
10367
  } catch (error) {
9746
- reject(error);
10368
+ resolve({
10369
+ status,
10370
+ signal,
10371
+ stdout,
10372
+ stderr: appendBounded2(stderr, `
10373
+ ${safeErrorMessage2(error)}`),
10374
+ outputText: ""
10375
+ });
9747
10376
  }
9748
10377
  });
9749
10378
  try {
@@ -9817,13 +10446,21 @@ function signalExitCode2(signal) {
9817
10446
  return 1;
9818
10447
  }
9819
10448
  }
9820
- async function readCodexOutput(outputPath, stdout) {
10449
+ async function readCodexOutput(outputPath, status) {
9821
10450
  try {
9822
- return await readFile6(outputPath, "utf8");
9823
- } catch {
9824
- return stdout;
10451
+ return await readFile7(outputPath, "utf8");
10452
+ } catch (error) {
10453
+ if (status === 0) {
10454
+ throw new Error(
10455
+ `Codex CLI exited successfully but did not write --output-last-message: ${safeErrorMessage2(error)}`
10456
+ );
10457
+ }
10458
+ return "";
9825
10459
  }
9826
10460
  }
10461
+ function safeErrorMessage2(error) {
10462
+ return error instanceof Error ? error.message : String(error);
10463
+ }
9827
10464
  function appendBounded2(existing, next) {
9828
10465
  const combined = existing + next;
9829
10466
  if (combined.length <= CODEX_CLI_STDIO_LIMIT) {
@@ -9894,35 +10531,89 @@ function codexCliAbortError(signal) {
9894
10531
  }
9895
10532
  return new DOMException("The operation was aborted.", "AbortError");
9896
10533
  }
10534
+ function codexCliPreStartAbortError(signal) {
10535
+ return new CodexCreditDispatchError(CODEX_CLI_PRE_START_ABORT_MESSAGE, {
10536
+ cause: codexCliAbortError(signal)
10537
+ });
10538
+ }
10539
+ function unwrapCodexCliPreStartAbort(error) {
10540
+ return error instanceof CodexCreditDispatchError && error.message === CODEX_CLI_PRE_START_ABORT_MESSAGE && error.cause instanceof Error ? error.cause : error;
10541
+ }
9897
10542
  function summarizeProcessOutput2(stderr, stdout) {
9898
10543
  const summary = [stderr.trim(), stdout.trim()].filter((value) => value.length > 0).join("\n").trim();
9899
10544
  return summary.length > 0 ? summary.slice(-1e3) : "no process output";
9900
10545
  }
9901
- function parseCodexTokenUsage(stderr, outputText) {
9902
- const totalTokens = parseCodexTotalTokens(stderr);
9903
- if (totalTokens === void 0) {
10546
+ function requireCodexJsonlUsage(result) {
10547
+ const usage = parseCodexJsonlUsage(`${result.stdout}
10548
+ ${result.stderr}`);
10549
+ if (!usage) {
10550
+ throw new Error(
10551
+ `Codex CLI completion did not emit a valid turn.completed usage event: ${summarizeProcessOutput2(result.stderr, result.stdout)}`
10552
+ );
10553
+ }
10554
+ return usage;
10555
+ }
10556
+ function readCodexUsage(result, outputText) {
10557
+ const exact = parseCodexJsonlUsage(`${result.stdout}
10558
+ ${result.stderr}`);
10559
+ if (exact) return exact;
10560
+ const legacy = parseCodexTokenUsage(
10561
+ `${result.stderr}
10562
+ ${result.stdout}`,
10563
+ outputText
10564
+ );
10565
+ return {
10566
+ inputTokens: legacy.input,
10567
+ cachedInputTokens: 0,
10568
+ outputTokens: legacy.output,
10569
+ reasoningOutputTokens: 0
10570
+ };
10571
+ }
10572
+ function parseCodexTokenUsage(output, outputText) {
10573
+ const matches = [...output.matchAll(/\btokens used\s+([0-9][0-9,]*)\b/gi)];
10574
+ const raw = matches.at(-1)?.[1];
10575
+ if (!raw) return { input: 0, output: 0 };
10576
+ const totalTokens = Number(raw.replace(/,/g, ""));
10577
+ if (!Number.isSafeInteger(totalTokens) || totalTokens < 0) {
9904
10578
  return { input: 0, output: 0 };
9905
10579
  }
9906
- const estimatedOutputTokens = Math.min(
10580
+ const outputTokens = Math.min(
9907
10581
  totalTokens,
9908
10582
  Math.max(1, Math.ceil(outputText.length / 4))
9909
10583
  );
9910
- return {
9911
- input: totalTokens - estimatedOutputTokens,
9912
- output: estimatedOutputTokens
9913
- };
10584
+ return { input: totalTokens - outputTokens, output: outputTokens };
10585
+ }
10586
+ function codexCliResultError(result) {
10587
+ const exitLabel = result.signal ? `signal ${result.signal}` : `exit ${result.status ?? "unknown"}`;
10588
+ return new Error(
10589
+ `Codex CLI completion failed (${exitLabel}): ${summarizeProcessOutput2(result.stderr, result.stdout)}`
10590
+ );
10591
+ }
10592
+ function tomlString(value) {
10593
+ return JSON.stringify(value);
10594
+ }
10595
+ function buildCodexStructuredJudgePrompt(rubric) {
10596
+ return [
10597
+ rubric,
10598
+ "Return raw JSON only, with exactly these keys:",
10599
+ '{"score":<number from 0 to 1>,"decision":"pass|partial|fail","reason":"non-empty concise reason"}',
10600
+ "Do not wrap the JSON in Markdown or add any other text."
10601
+ ].join("\n\n");
10602
+ }
10603
+ function buildCodexAssistantRubricPrompt(systemPrompt) {
10604
+ return [
10605
+ systemPrompt,
10606
+ "Return raw JSON only, with exactly these keys:",
10607
+ '{"identity_accuracy":<0-5>,"stance_coherence":<0-5>,"novelty":<0-5>,"calibration":<0-5>,"notes":"string"}',
10608
+ "Every numeric value must be finite and within the inclusive range 0 to 5.",
10609
+ "Do not wrap the JSON in Markdown or add any other text."
10610
+ ].join("\n\n");
9914
10611
  }
9915
- function parseCodexTotalTokens(stderr) {
9916
- const matches = [...stderr.matchAll(/\btokens used\s+([0-9][0-9,]*)\b/gi)];
9917
- const raw = matches.at(-1)?.[1];
9918
- if (!raw) {
9919
- return void 0;
9920
- }
9921
- const parsed = Number(raw.replace(/,/g, ""));
9922
- return Number.isSafeInteger(parsed) && parsed >= 0 ? parsed : void 0;
10612
+ function isCodexStructuredJudgeAbort(error, signal) {
10613
+ return signal?.aborted === true || error instanceof DOMException && error.name === "AbortError" || error instanceof Error && error.name === "AbortError";
9923
10614
  }
9924
- function tomlString(value) {
9925
- return JSON.stringify(value);
10615
+ function structuredJudgeErrorName(error) {
10616
+ return error instanceof Error && error.name.trim().length > 0 ? error.name : "unknown error";
9926
10617
  }
9927
10618
  function createCodexCliProvider(config, deps) {
9928
10619
  return new CodexCliProvider(config, deps);
@@ -9930,28 +10621,28 @@ function createCodexCliProvider(config, deps) {
9930
10621
 
9931
10622
  // src/reporter.ts
9932
10623
  import { execSync } from "child_process";
9933
- import { mkdir as mkdir7, readFile as readFile7, writeFile as writeFile7 } from "fs/promises";
9934
- import path10 from "path";
10624
+ import { mkdir as mkdir8, readFile as readFile8, writeFile as writeFile8 } from "fs/promises";
10625
+ import path11 from "path";
9935
10626
 
9936
10627
  // src/filename-safety.ts
9937
- import path8 from "path";
10628
+ import path9 from "path";
9938
10629
  function sanitizeFilenameSegment(value) {
9939
10630
  const sanitized = value.trim().replace(/[^a-zA-Z0-9._-]/g, "_");
9940
10631
  return sanitized.length > 0 ? sanitized : "unknown";
9941
10632
  }
9942
10633
  function resolveContainedPath(root, ...segments) {
9943
- const outputRoot = path8.resolve(root);
9944
- const filePath = path8.resolve(outputRoot, ...segments);
9945
- const relativePath = path8.relative(outputRoot, filePath);
9946
- if (relativePath === ".." || relativePath.startsWith(`..${path8.sep}`) || path8.isAbsolute(relativePath)) {
10634
+ const outputRoot = path9.resolve(root);
10635
+ const filePath = path9.resolve(outputRoot, ...segments);
10636
+ const relativePath = path9.relative(outputRoot, filePath);
10637
+ if (relativePath === ".." || relativePath.startsWith(`..${path9.sep}`) || path9.isAbsolute(relativePath)) {
9947
10638
  throw new Error(`Refusing to write benchmark artifact outside ${outputRoot}`);
9948
10639
  }
9949
10640
  return filePath;
9950
10641
  }
9951
10642
 
9952
10643
  // src/leaderboard-export.ts
9953
- import { mkdir as mkdir6, writeFile as writeFile6 } from "fs/promises";
9954
- import path9 from "path";
10644
+ import { mkdir as mkdir7, writeFile as writeFile7 } from "fs/promises";
10645
+ import path10 from "path";
9955
10646
  async function writeLeaderboardArtifactsForResult(result, outputDir) {
9956
10647
  if (result.meta.benchmark === "ama-bench") {
9957
10648
  return writeAmaBenchLeaderboard(result, outputDir);
@@ -9966,12 +10657,12 @@ async function writeAmaBenchLeaderboard(result, outputDir) {
9966
10657
  if (rows.length === 0) {
9967
10658
  return [];
9968
10659
  }
9969
- const outputRoot = path9.resolve(outputDir);
10660
+ const outputRoot = path10.resolve(outputDir);
9970
10661
  const leaderboardDir = resolveContainedPath(outputRoot, "leaderboard");
9971
- await mkdir6(leaderboardDir, { recursive: true });
10662
+ await mkdir7(leaderboardDir, { recursive: true });
9972
10663
  const timestamp = sanitizeFilenameSegment(result.meta.timestamp.replace(/[:.]/g, "-"));
9973
10664
  const filePath = resolveContainedPath(leaderboardDir, `ama-bench-${timestamp}-answers.jsonl`);
9974
- await writeFile6(filePath, serializeJsonl(rows), "utf8");
10665
+ await writeFile7(filePath, serializeJsonl(rows), "utf8");
9975
10666
  return [
9976
10667
  {
9977
10668
  benchmark: "ama-bench",
@@ -9984,16 +10675,16 @@ async function writeAmaBenchLeaderboard(result, outputDir) {
9984
10675
  async function writeMemCorrectLeaderboard(result, outputDir) {
9985
10676
  const row = buildMemCorrectLeaderboardRow(result);
9986
10677
  if (!row) return [];
9987
- const outputRoot = path9.resolve(outputDir);
10678
+ const outputRoot = path10.resolve(outputDir);
9988
10679
  const leaderboardDir = resolveContainedPath(outputRoot, "leaderboard");
9989
- await mkdir6(leaderboardDir, { recursive: true });
10680
+ await mkdir7(leaderboardDir, { recursive: true });
9990
10681
  const timestamp = sanitizeFilenameSegment(result.meta.timestamp.replace(/[:.]/g, "-"));
9991
10682
  const safeAdapter = sanitizeFilenameSegment(row.adapter);
9992
10683
  const filePath = resolveContainedPath(
9993
10684
  leaderboardDir,
9994
10685
  `memcorrect-${safeAdapter}-${timestamp}.jsonl`
9995
10686
  );
9996
- await writeFile6(filePath, `${JSON.stringify(row)}
10687
+ await writeFile7(filePath, `${JSON.stringify(row)}
9997
10688
  `, "utf8");
9998
10689
  return [
9999
10690
  {
@@ -10352,8 +11043,8 @@ function replaceLoneSurrogates(value) {
10352
11043
  return out;
10353
11044
  }
10354
11045
  async function writeBenchmarkResult(result, outputDir) {
10355
- const outputRoot = path10.resolve(outputDir);
10356
- await mkdir7(outputRoot, { recursive: true });
11046
+ const outputRoot = path11.resolve(outputDir);
11047
+ await mkdir8(outputRoot, { recursive: true });
10357
11048
  const safeBenchmark = sanitizeFilenameSegment(result.meta.benchmark);
10358
11049
  const safeRemnicVersion = sanitizeFilenameSegment(result.meta.remnicVersion);
10359
11050
  const timestamp = sanitizeFilenameSegment(result.meta.timestamp.replace(/[:.]/g, "-"));
@@ -10381,14 +11072,14 @@ async function writeBenchmarkResult(result, outputDir) {
10381
11072
  }
10382
11073
  };
10383
11074
  const publicResult = sanitizeBenchmarkResultForJson(redactBenchmarkResultSecrets(resultWithArtifacts));
10384
- await writeFile7(filePath, `${JSON.stringify(publicResult, null, 2)}
11075
+ await writeFile8(filePath, `${JSON.stringify(publicResult, null, 2)}
10385
11076
  `);
10386
11077
  return filePath;
10387
11078
  }
10388
11079
  async function getRemnicVersion() {
10389
11080
  try {
10390
11081
  const packageJson = JSON.parse(
10391
- await readFile7(path10.resolve(import.meta.dirname, "../../../package.json"), "utf8")
11082
+ await readFile8(path11.resolve(import.meta.dirname, "../../../package.json"), "utf8")
10392
11083
  );
10393
11084
  return typeof packageJson.version === "string" ? packageJson.version : "unknown";
10394
11085
  } catch {
@@ -11641,52 +12332,8 @@ function asStringArray(value) {
11641
12332
  // src/responders.ts
11642
12333
  import { FallbackLlmClient } from "@remnic/core";
11643
12334
 
11644
- // src/judges/memcorrect-rubrics.ts
11645
- var OPENAI_RESPONSES_JUDGE_RUBRIC_VERSION = "openai-responses-bench-v1";
11646
- var MEMCORRECT_CORRECTION_ACCEPTANCE_RUBRIC_VERSION = "memcorrect-correction-acceptance-v1";
11647
- var MEMCORRECT_STALE_HARM_RUBRIC_VERSION = "memcorrect-stale-memory-harm-v1";
11648
- var GENERAL_ANSWER_JUDGE_RUBRIC = [
11649
- "Grade the predicted benchmark answer against the reference answer.",
11650
- "A score of 1 means fully correct, 0 means fully incorrect, and values between 0 and 1 mean partially correct.",
11651
- "Do not reward unsupported claims. Ignore harmless wording and formatting differences."
11652
- ].join(" ");
11653
- var MEMCORRECT_CORRECTION_ACCEPTANCE_RUBRIC = [
11654
- "Decide whether the memory system accepted the user's correction.",
11655
- "Pass only when the corrected fact is reflected and the retired fact is not asserted as current.",
11656
- "A quotation or correction-history record that clearly marks the retired fact as obsolete is not stale recall.",
11657
- "Use a score of 1 for accepted, 0 for not accepted, and a fractional score only when the evidence is genuinely ambiguous."
11658
- ].join(" ");
11659
- var MEMCORRECT_STALE_HARM_RUBRIC = [
11660
- "Decide whether the memory system avoided stale-memory harm after a correction.",
11661
- "Pass only when the answer does not present the retired fact as current and does not act on it.",
11662
- "Correction provenance may mention the retired fact only when it is explicitly identified as obsolete.",
11663
- "Use a score of 1 when no stale harm is present, 0 when stale information affected the answer, and a fractional score only for genuinely ambiguous evidence."
11664
- ].join(" ");
11665
-
11666
12335
  // src/providers/openai-responses.ts
11667
12336
  var DEFAULT_OPENAI_RESPONSES_JUDGE_MODEL = "gpt-5.6";
11668
- var VERDICT_JSON_SCHEMA = {
11669
- type: "object",
11670
- additionalProperties: false,
11671
- required: ["score", "decision", "reason"],
11672
- properties: {
11673
- score: { type: "number", minimum: 0, maximum: 1 },
11674
- decision: { type: "string", enum: ["pass", "partial", "fail"] },
11675
- reason: { type: "string" }
11676
- }
11677
- };
11678
- var ASSISTANT_RUBRIC_JSON_SCHEMA = {
11679
- type: "object",
11680
- additionalProperties: false,
11681
- required: ["identity_accuracy", "stance_coherence", "novelty", "calibration", "notes"],
11682
- properties: {
11683
- identity_accuracy: { type: "number", minimum: 0, maximum: 5 },
11684
- stance_coherence: { type: "number", minimum: 0, maximum: 5 },
11685
- novelty: { type: "number", minimum: 0, maximum: 5 },
11686
- calibration: { type: "number", minimum: 0, maximum: 5 },
11687
- notes: { type: "string" }
11688
- }
11689
- };
11690
12337
  var OpenAiResponsesJudgeError = class extends Error {
11691
12338
  code;
11692
12339
  retryable;
@@ -11825,7 +12472,7 @@ var OpenAiResponsesProvider = class {
11825
12472
  this.recordTelemetry(failure.telemetry);
11826
12473
  return failure;
11827
12474
  }
11828
- const verdict = parseVerdict(parsed.text);
12475
+ const verdict = parseStructuredJudgeVerdict(parsed.text);
11829
12476
  if (!verdict) {
11830
12477
  const failure = this.failure(
11831
12478
  "malformed_verdict",
@@ -11879,7 +12526,7 @@ var OpenAiResponsesProvider = class {
11879
12526
  this.recordTelemetry(parsed.telemetry);
11880
12527
  throw new OpenAiResponsesJudgeError(parsed);
11881
12528
  }
11882
- if (parsed.text === null || !parseAssistantRubric(parsed.text)) {
12529
+ if (parsed.text === null || !isValidAssistantRubric(parsed.text)) {
11883
12530
  const failure = this.failure(
11884
12531
  "malformed_verdict",
11885
12532
  "OpenAI Responses API returned an invalid sealed assistant-rubric verdict.",
@@ -11901,6 +12548,9 @@ var OpenAiResponsesProvider = class {
11901
12548
  getTelemetryEvents() {
11902
12549
  return this.telemetryEvents.map((event) => ({ ...event }));
11903
12550
  }
12551
+ createJudgeError(failure) {
12552
+ return new OpenAiResponsesJudgeError(failure);
12553
+ }
11904
12554
  async parseResponse(response, startedAt, rubricVersion) {
11905
12555
  let payload;
11906
12556
  try {
@@ -12052,61 +12702,10 @@ function createOpenAiResponsesProvider(config = {}) {
12052
12702
  return new OpenAiResponsesProvider(config);
12053
12703
  }
12054
12704
  function createOpenAiResponsesBenchJudge(config = {}, provider = createOpenAiResponsesProvider(config)) {
12055
- const scoreWithMetrics = async (question, predicted, expected, control) => {
12056
- const result = await provider.judge({
12057
- rubric: GENERAL_ANSWER_JUDGE_RUBRIC,
12058
- rubricVersion: config.rubricVersion ?? OPENAI_RESPONSES_JUDGE_RUBRIC_VERSION,
12059
- input: [
12060
- `QUESTION: ${question}`,
12061
- `REFERENCE_ANSWER: ${expected}`,
12062
- `PREDICTED_ANSWER: ${predicted}`
12063
- ].join("\n\n"),
12064
- signal: control?.signal
12065
- });
12066
- if (!result.ok) throw new OpenAiResponsesJudgeError(result);
12067
- return toBenchJudgeResult(result);
12068
- };
12069
- const scoreBinaryPrompt = async (prompt, control) => {
12070
- const result = await provider.judge({
12071
- rubric: `${GENERAL_ANSWER_JUDGE_RUBRIC} This evaluator is binary: score must be exactly 0 or 1.`,
12072
- rubricVersion: config.rubricVersion ?? OPENAI_RESPONSES_JUDGE_RUBRIC_VERSION,
12073
- input: prompt,
12074
- signal: control?.signal
12075
- });
12076
- if (!result.ok) throw new OpenAiResponsesJudgeError(result);
12077
- if (result.verdict.score !== 0 && result.verdict.score !== 1) {
12078
- const failure = {
12079
- ok: false,
12080
- error: {
12081
- code: "malformed_verdict",
12082
- message: "OpenAI Responses API returned a non-binary verdict for a binary rubric.",
12083
- retryable: false
12084
- },
12085
- telemetry: { ...result.telemetry, errorCode: "malformed_verdict" }
12086
- };
12087
- throw new OpenAiResponsesJudgeError(failure);
12088
- }
12089
- return toBenchJudgeResult(result);
12090
- };
12091
- const judgeSpecialized = async (request, rubric, control) => {
12092
- const result = rubric === "correction" ? await judgeMemCorrectCorrectionAcceptance(provider, serializeMemCorrectJudgeRequest(request), control?.signal) : await judgeMemCorrectStaleMemoryHarm(provider, serializeMemCorrectJudgeRequest(request), control?.signal);
12093
- if (!result.ok) throw new OpenAiResponsesJudgeError(result);
12094
- return {
12095
- ...toBenchJudgeResult(result),
12096
- decision: result.verdict.decision,
12097
- reason: result.verdict.reason,
12098
- rubricVersion: result.telemetry.rubricVersion
12099
- };
12100
- };
12101
- return {
12102
- async score(question, predicted, expected, control) {
12103
- return (await scoreWithMetrics(question, predicted, expected, control)).score;
12104
- },
12105
- scoreWithMetrics,
12106
- scoreBinaryPrompt,
12107
- judgeMemCorrectCorrectionAcceptance: (request, control) => judgeSpecialized(request, "correction", control),
12108
- judgeMemCorrectStaleMemoryHarm: (request, control) => judgeSpecialized(request, "stale_harm", control)
12109
- };
12705
+ return createStructuredBenchJudge(
12706
+ provider,
12707
+ config.rubricVersion ?? OPENAI_RESPONSES_JUDGE_RUBRIC_VERSION
12708
+ );
12110
12709
  }
12111
12710
  async function judgeMemCorrectCorrectionAcceptance(provider, input, signal) {
12112
12711
  return provider.judge({
@@ -12124,17 +12723,6 @@ async function judgeMemCorrectStaleMemoryHarm(provider, input, signal) {
12124
12723
  signal
12125
12724
  });
12126
12725
  }
12127
- function toBenchJudgeResult(result) {
12128
- return {
12129
- score: result.verdict.score,
12130
- tokens: {
12131
- input: result.telemetry.inputTokens,
12132
- output: result.telemetry.outputTokens
12133
- },
12134
- latencyMs: result.telemetry.latencyMs,
12135
- model: result.telemetry.model
12136
- };
12137
- }
12138
12726
  function normalizeModel(model) {
12139
12727
  if (model === void 0) return DEFAULT_OPENAI_RESPONSES_JUDGE_MODEL;
12140
12728
  const trimmed = model.trim();
@@ -12143,54 +12731,6 @@ function normalizeModel(model) {
12143
12731
  }
12144
12732
  return trimmed;
12145
12733
  }
12146
- function parseVerdict(text) {
12147
- let parsed;
12148
- try {
12149
- parsed = JSON.parse(text);
12150
- } catch {
12151
- return null;
12152
- }
12153
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
12154
- const candidate = parsed;
12155
- const keys = Object.keys(candidate).sort();
12156
- if (keys.join(",") !== "decision,reason,score") return null;
12157
- if (typeof candidate.score !== "number" || !Number.isFinite(candidate.score) || candidate.score < 0 || candidate.score > 1 || candidate.decision !== "pass" && candidate.decision !== "partial" && candidate.decision !== "fail" || typeof candidate.reason !== "string" || candidate.reason.trim().length === 0) {
12158
- return null;
12159
- }
12160
- return {
12161
- score: candidate.score,
12162
- decision: candidate.decision,
12163
- reason: candidate.reason.trim()
12164
- };
12165
- }
12166
- function parseAssistantRubric(text) {
12167
- let parsed;
12168
- try {
12169
- parsed = JSON.parse(text);
12170
- } catch {
12171
- return false;
12172
- }
12173
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return false;
12174
- const candidate = parsed;
12175
- const keys = Object.keys(candidate).sort();
12176
- if (keys.join(",") !== "calibration,identity_accuracy,notes,novelty,stance_coherence") return false;
12177
- return ["identity_accuracy", "stance_coherence", "novelty", "calibration"].every(
12178
- (key) => typeof candidate[key] === "number" && Number.isFinite(candidate[key]) && candidate[key] >= 0 && candidate[key] <= 5
12179
- ) && typeof candidate.notes === "string";
12180
- }
12181
- function serializeMemCorrectJudgeRequest(request) {
12182
- return JSON.stringify({
12183
- taskId: request.taskId,
12184
- query: request.query,
12185
- retiredContent: request.retiredContent,
12186
- correctedContent: request.correctedContent,
12187
- evidence: {
12188
- postCorrectionRecall: request.postCorrectionRecall,
12189
- postMaintenanceRecall: request.postMaintenanceRecall,
12190
- postReingestRecall: request.postReingestRecall
12191
- }
12192
- });
12193
- }
12194
12734
  function readOutputText(payload) {
12195
12735
  const text = (payload.output ?? []).flatMap((item) => item.type === "message" ? item.content ?? [] : []).filter((part) => part.type === "output_text").map((part) => part.text ?? "").join("").trim();
12196
12736
  return text.length > 0 ? text : null;
@@ -12715,10 +13255,11 @@ function createJudgeFromProvider(provider) {
12715
13255
  }
12716
13256
  function createProviderBackedJudge(config, providerInstance) {
12717
13257
  validateProviderConfig(config, "judge");
12718
- if (config.provider === "openai" && providerInstance === void 0) {
12719
- return createOpenAiResponsesBenchJudge({ ...config, provider: "openai" });
13258
+ const provider = providerInstance ?? createJudgeProvider(config);
13259
+ if (isStructuredJudgeProvider(provider)) {
13260
+ return createStructuredBenchJudge(provider, config.rubricVersion);
12720
13261
  }
12721
- return createJudgeFromProvider(providerInstance ?? createProvider(config));
13262
+ return createJudgeFromProvider(provider);
12722
13263
  }
12723
13264
  function createAmaBenchRecommendedJudgeFromProvider(provider) {
12724
13265
  async function scoreWithMetrics(question, predicted, expected, control) {
@@ -12771,15 +13312,16 @@ function createStructuredJudgeFromProvider(provider) {
12771
13312
  }
12772
13313
  function createProviderBackedStructuredJudge(config, providerInstance) {
12773
13314
  validateProviderConfig(config, "judge");
12774
- if (config.provider === "openai" && providerInstance === void 0) {
12775
- const provider = createOpenAiResponsesProvider({ ...config, provider: "openai" });
13315
+ const provider = providerInstance ?? createJudgeProvider(config);
13316
+ if (isStructuredJudgeProvider(provider)) {
12776
13317
  return {
12777
13318
  evaluate: (request) => provider.evaluateAssistantRubric(request)
12778
13319
  };
12779
13320
  }
12780
- return createStructuredJudgeFromProvider(
12781
- providerInstance ?? createProvider(config)
12782
- );
13321
+ return createStructuredJudgeFromProvider(provider);
13322
+ }
13323
+ function createJudgeProvider(config) {
13324
+ return config.provider === "openai" ? createOpenAiResponsesProvider({ ...config, provider: "openai" }) : createProvider(config);
12783
13325
  }
12784
13326
  function createGatewayResponder(options) {
12785
13327
  if (!options.gatewayConfig) {
@@ -13052,8 +13594,8 @@ function clampNormalizedScore(value) {
13052
13594
  }
13053
13595
 
13054
13596
  // src/runtime-profiles.ts
13055
- import path11 from "path";
13056
- import { readFile as readFile9 } from "fs/promises";
13597
+ import path12 from "path";
13598
+ import { readFile as readFile10 } from "fs/promises";
13057
13599
  import {
13058
13600
  resolvePluginEntry,
13059
13601
  setCodexCliFallbackRunnerForProcess
@@ -13401,7 +13943,7 @@ function buildPromptSpecificRequirements(prompt) {
13401
13943
  }
13402
13944
 
13403
13945
  // src/local-lab/manifest.ts
13404
- import { readFile as readFile8 } from "fs/promises";
13946
+ import { readFile as readFile9 } from "fs/promises";
13405
13947
  var LOCAL_LAB_PROVIDER_KINDS = [
13406
13948
  "openai-compatible",
13407
13949
  "ollama"
@@ -13438,7 +13980,7 @@ function parseLocalLabManifest(raw) {
13438
13980
  async function loadLocalLabManifest(filePath) {
13439
13981
  let text;
13440
13982
  try {
13441
- text = await readFile8(filePath, "utf8");
13983
+ text = await readFile9(filePath, "utf8");
13442
13984
  } catch (error) {
13443
13985
  const code = error?.code ?? "EUNKNOWN";
13444
13986
  throw new Error(`local-lab manifest at ${filePath} could not be read (${code})`);
@@ -14099,14 +14641,14 @@ async function loadOpenclawRuntimeConfig(filePath) {
14099
14641
  };
14100
14642
  }
14101
14643
  function deriveOpenclawRuntimeContext(configPath) {
14102
- const rootDir = path11.dirname(path11.resolve(configPath));
14644
+ const rootDir = path12.dirname(path12.resolve(configPath));
14103
14645
  return {
14104
- agentDir: path11.join(rootDir, "agents", "main", "agent"),
14105
- workspaceDir: path11.join(rootDir, "workspace")
14646
+ agentDir: path12.join(rootDir, "agents", "main", "agent"),
14647
+ workspaceDir: path12.join(rootDir, "workspace")
14106
14648
  };
14107
14649
  }
14108
14650
  async function loadJsonObject(filePath, label) {
14109
- const raw = await readFile9(filePath, "utf8");
14651
+ const raw = await readFile10(filePath, "utf8");
14110
14652
  let parsed;
14111
14653
  try {
14112
14654
  parsed = JSON.parse(raw);
@@ -14518,20 +15060,20 @@ async function resolveLocalLabRuntimeProfile(options) {
14518
15060
 
14519
15061
  // src/benchmark.ts
14520
15062
  import fs2 from "fs";
14521
- import path34 from "path";
15063
+ import path35 from "path";
14522
15064
  import { createHash as createHash11 } from "crypto";
14523
15065
  import { expandTildePath as expandTildePath3 } from "@remnic/core";
14524
15066
 
14525
15067
  // src/judges/judge-cache.ts
14526
15068
  import { createHash as createHash6, randomBytes as randomBytes2 } from "crypto";
14527
15069
  import {
14528
- mkdir as mkdir8,
14529
- readFile as readFile10,
14530
- rename as rename2,
15070
+ mkdir as mkdir9,
15071
+ readFile as readFile11,
15072
+ rename as rename3,
14531
15073
  rm as rm4,
14532
- writeFile as writeFile8
15074
+ writeFile as writeFile9
14533
15075
  } from "fs/promises";
14534
- import path12 from "path";
15076
+ import path13 from "path";
14535
15077
  var JUDGE_CACHE_PROTOCOL_VERSION = "judge-protocol-v1";
14536
15078
  function stableStringify2(value) {
14537
15079
  if (Array.isArray(value)) {
@@ -14562,7 +15104,7 @@ var JudgeCache = class {
14562
15104
  inflight = /* @__PURE__ */ new Map();
14563
15105
  cachedDirExists = false;
14564
15106
  constructor(options) {
14565
- this.dir = path12.resolve(options.dir);
15107
+ this.dir = path13.resolve(options.dir);
14566
15108
  }
14567
15109
  /** Compute the sha256-hex key for a set of parts. Pure, sync, side-effect-free. */
14568
15110
  computeKey(parts) {
@@ -14587,7 +15129,7 @@ var JudgeCache = class {
14587
15129
  const filePath = this.entryPath(key);
14588
15130
  let raw;
14589
15131
  try {
14590
- raw = await readFile10(filePath, "utf8");
15132
+ raw = await readFile11(filePath, "utf8");
14591
15133
  } catch {
14592
15134
  return void 0;
14593
15135
  }
@@ -14633,25 +15175,25 @@ var JudgeCache = class {
14633
15175
  }
14634
15176
  async writeOne(key, envelope) {
14635
15177
  if (!this.cachedDirExists) {
14636
- await mkdir8(this.dir, { recursive: true });
15178
+ await mkdir9(this.dir, { recursive: true });
14637
15179
  this.cachedDirExists = true;
14638
15180
  }
14639
15181
  const filePath = this.entryPath(key);
14640
- const tempPath = path12.join(
15182
+ const tempPath = path13.join(
14641
15183
  this.dir,
14642
15184
  `.${key}.${randomBytes2(6).toString("hex")}.tmp`
14643
15185
  );
14644
- await writeFile8(tempPath, `${JSON.stringify(envelope)}
15186
+ await writeFile9(tempPath, `${JSON.stringify(envelope)}
14645
15187
  `, "utf8");
14646
15188
  try {
14647
- await rename2(tempPath, filePath);
15189
+ await rename3(tempPath, filePath);
14648
15190
  } catch (error) {
14649
15191
  await rm4(tempPath, { force: true }).catch(() => void 0);
14650
15192
  throw error;
14651
15193
  }
14652
15194
  }
14653
15195
  entryPath(key) {
14654
- return path12.join(this.dir, `${key}.json`);
15196
+ return path13.join(this.dir, `${key}.json`);
14655
15197
  }
14656
15198
  };
14657
15199
  function runJudgeWithCache(options) {
@@ -14841,8 +15383,8 @@ function isBenchJudgeResult(value) {
14841
15383
 
14842
15384
  // src/benchmarks/published/ama-bench/runner.ts
14843
15385
  import { randomUUID as randomUUID2 } from "crypto";
14844
- import { readFile as readFile11 } from "fs/promises";
14845
- import path13 from "path";
15386
+ import { readFile as readFile12 } from "fs/promises";
15387
+ import path14 from "path";
14846
15388
 
14847
15389
  // src/benchmarks/published/ama-bench/fixture.ts
14848
15390
  var AMA_BENCH_SMOKE_FIXTURE = [
@@ -15417,10 +15959,10 @@ async function loadDataset(mode, datasetDir, limit) {
15417
15959
  return episodes;
15418
15960
  };
15419
15961
  if (datasetDir) {
15420
- const filePath = path13.join(datasetDir, "open_end_qa_set.jsonl");
15962
+ const filePath = path14.join(datasetDir, "open_end_qa_set.jsonl");
15421
15963
  let raw;
15422
15964
  try {
15423
- raw = await readFile11(filePath, "utf8");
15965
+ raw = await readFile12(filePath, "utf8");
15424
15966
  } catch (error) {
15425
15967
  throw new Error(
15426
15968
  `AMA-Bench dataset not found at ${filePath}: ${error instanceof Error ? error.message : String(error)}`
@@ -15712,8 +16254,8 @@ function isValidQaPairs(value) {
15712
16254
 
15713
16255
  // src/benchmarks/published/amemgym/runner.ts
15714
16256
  import { randomUUID as randomUUID3 } from "crypto";
15715
- import { readFile as readFile12 } from "fs/promises";
15716
- import path14 from "path";
16257
+ import { readFile as readFile13 } from "fs/promises";
16258
+ import path15 from "path";
15717
16259
 
15718
16260
  // src/benchmarks/published/amemgym/fixture.ts
15719
16261
  var AMEMGYM_SMOKE_FIXTURE = [
@@ -16242,7 +16784,7 @@ async function loadDataset2(mode, datasetDir, limit) {
16242
16784
  const datasetErrors = [];
16243
16785
  for (const filename of DATASET_FILENAMES) {
16244
16786
  try {
16245
- const raw = await readFile12(path14.join(datasetDir, filename), "utf8");
16787
+ const raw = await readFile13(path15.join(datasetDir, filename), "utf8");
16246
16788
  const parsed = parseDataset(raw, filename, normalizedLimit);
16247
16789
  return ensureDatasetProfiles(parsed);
16248
16790
  } catch (error) {
@@ -16416,8 +16958,8 @@ function normalizeRole(role) {
16416
16958
 
16417
16959
  // src/benchmarks/published/memory-arena/runner.ts
16418
16960
  import { randomUUID as randomUUID4 } from "crypto";
16419
- import { readFile as readFile13, readdir as readdir5, stat as stat3 } from "fs/promises";
16420
- import path15 from "path";
16961
+ import { readFile as readFile14, readdir as readdir5, stat as stat3 } from "fs/promises";
16962
+ import path16 from "path";
16421
16963
  import { expandTildePath as expandTildePath2 } from "@remnic/core";
16422
16964
 
16423
16965
  // src/benchmarks/published/memory-arena/fixture.ts
@@ -16744,7 +17286,7 @@ async function loadDataset3(mode, datasetDir, limit) {
16744
17286
  if (remainingLimit2 === 0) {
16745
17287
  break;
16746
17288
  }
16747
- const raw = await readFile13(path15.join(datasetDir, filename), "utf8");
17289
+ const raw = await readFile14(path16.join(datasetDir, filename), "utf8");
16748
17290
  const parsedTasks = [];
16749
17291
  raw.split("\n").forEach((line, lineIndex) => {
16750
17292
  if (line.trim().length === 0) {
@@ -17080,7 +17622,7 @@ async function loadMemoryArenaWebshopProductCatalog(datasetDir) {
17080
17622
  `MemoryArena WebShop product sidecar is ${sourceStat.size} bytes; provide a compact JSON/JSONL sidecar smaller than ${MEMORY_ARENA_WEBSHOP_PRODUCTS_MAX_BYTES} bytes instead of the full WebShop catalog.`
17081
17623
  );
17082
17624
  }
17083
- const raw = await readFile13(sourcePath, "utf8");
17625
+ const raw = await readFile14(sourcePath, "utf8");
17084
17626
  const records = parseMemoryArenaWebshopSidecarRecords(raw, sourcePath);
17085
17627
  const byAsin = /* @__PURE__ */ new Map();
17086
17628
  for (const record of records) {
@@ -17100,14 +17642,14 @@ async function loadMemoryArenaWebshopProductCatalog(datasetDir) {
17100
17642
  async function resolveMemoryArenaWebshopProductCatalogPath(datasetDir) {
17101
17643
  const configuredPath = process.env[MEMORY_ARENA_WEBSHOP_PRODUCTS_ENV]?.trim();
17102
17644
  if (configuredPath && configuredPath.length > 0) {
17103
- return path15.resolve(expandTildePath2(configuredPath));
17645
+ return path16.resolve(expandTildePath2(configuredPath));
17104
17646
  }
17105
17647
  if (datasetDir === void 0) {
17106
17648
  return void 0;
17107
17649
  }
17108
17650
  const candidatePaths = [
17109
17651
  ...MEMORY_ARENA_WEBSHOP_PRODUCT_SIDECAR_FILENAMES
17110
- ].map((filename) => path15.join(datasetDir, filename));
17652
+ ].map((filename) => path16.join(datasetDir, filename));
17111
17653
  for (const candidatePath of candidatePaths) {
17112
17654
  try {
17113
17655
  const candidateStat = await stat3(candidatePath);
@@ -18529,8 +19071,8 @@ function scoreSubtaskSuccess(scores) {
18529
19071
  import { collectTemporalLexicalCues } from "@remnic/core";
18530
19072
 
18531
19073
  // src/benchmarks/published/dataset-loader.ts
18532
- import { readFile as readFile14 } from "fs/promises";
18533
- import path16 from "path";
19074
+ import { readFile as readFile15 } from "fs/promises";
19075
+ import path17 from "path";
18534
19076
 
18535
19077
  // src/benchmarks/published/longmemeval/fixture.ts
18536
19078
  var LONG_MEM_EVAL_SMOKE_FIXTURE = [
@@ -18633,10 +19175,10 @@ async function loadDataset4(options) {
18633
19175
  const errors = [];
18634
19176
  if (options.datasetDir) {
18635
19177
  for (const filename of options.filenames) {
18636
- const abs = path16.join(options.datasetDir, filename);
19178
+ const abs = path17.join(options.datasetDir, filename);
18637
19179
  let raw;
18638
19180
  try {
18639
- raw = await readFile14(abs, "utf8");
19181
+ raw = await readFile15(abs, "utf8");
18640
19182
  } catch (error) {
18641
19183
  errors.push(
18642
19184
  `${filename}: ${error instanceof Error ? error.message : String(error)}`
@@ -20743,7 +21285,7 @@ function normalizeQaArray(value, location) {
20743
21285
  import { randomUUID as randomUUID6 } from "crypto";
20744
21286
  import { createReadStream as createReadStream2 } from "fs";
20745
21287
  import { readdir as readdir6 } from "fs/promises";
20746
- import path17 from "path";
21288
+ import path18 from "path";
20747
21289
  import { createInterface } from "readline/promises";
20748
21290
  import {
20749
21291
  asyncBufferFromFile,
@@ -21214,8 +21756,8 @@ async function listBeamDatasetFiles(datasetDir) {
21214
21756
  return directFiles;
21215
21757
  }
21216
21758
  try {
21217
- const nestedFilenames = await readdir6(path17.join(datasetDir, "data"));
21218
- return nestedFilenames.filter((filename) => isBeamDatasetFilename(filename)).map((filename) => path17.join("data", filename));
21759
+ const nestedFilenames = await readdir6(path18.join(datasetDir, "data"));
21760
+ return nestedFilenames.filter((filename) => isBeamDatasetFilename(filename)).map((filename) => path18.join("data", filename));
21219
21761
  } catch {
21220
21762
  return [];
21221
21763
  }
@@ -21242,7 +21784,7 @@ async function* iterateDatasetFiles(datasetDir, datasetFiles, limit) {
21242
21784
  let remainingLimit = limit;
21243
21785
  for (const filename of datasetFiles) {
21244
21786
  const scale = inferScaleFromFilename(filename);
21245
- const filePath = path17.join(datasetDir, filename);
21787
+ const filePath = path18.join(datasetDir, filename);
21246
21788
  const conversations = filename.endsWith(".jsonl") ? streamJsonlDataset(filePath, filename, remainingLimit) : filename.endsWith(".parquet") ? streamParquetDataset(filePath, filename, remainingLimit) : streamJsonDataset(filePath, filename, remainingLimit);
21247
21789
  for await (const conversation of conversations) {
21248
21790
  yield {
@@ -22254,8 +22796,8 @@ var StructuredLiteralParser = class {
22254
22796
 
22255
22797
  // src/benchmarks/published/personamem/runner.ts
22256
22798
  import { createHash as createHash7, randomUUID as randomUUID7 } from "crypto";
22257
- import { readFile as readFile15, realpath as realpath4 } from "fs/promises";
22258
- import path18 from "path";
22799
+ import { readFile as readFile16, realpath as realpath4 } from "fs/promises";
22800
+ import path19 from "path";
22259
22801
 
22260
22802
  // src/benchmarks/published/personamem/fixture.ts
22261
22803
  var PERSONAMEM_SMOKE_FIXTURE = [
@@ -22531,10 +23073,10 @@ async function loadDataset8(mode, datasetDir, limit) {
22531
23073
  if (datasetDir) {
22532
23074
  const datasetErrors = [];
22533
23075
  for (const relativePath of DATASET_FILE_CANDIDATES) {
22534
- const datasetPath = path18.join(datasetDir, relativePath);
23076
+ const datasetPath = path19.join(datasetDir, relativePath);
22535
23077
  let raw;
22536
23078
  try {
22537
- raw = await readFile15(datasetPath, "utf8");
23079
+ raw = await readFile16(datasetPath, "utf8");
22538
23080
  } catch (error) {
22539
23081
  datasetErrors.push(
22540
23082
  `${relativePath}: ${error instanceof Error ? error.message : String(error)}`
@@ -22592,7 +23134,7 @@ async function hydrateSample(row, datasetRoot) {
22592
23134
  datasetRoot,
22593
23135
  row.chat_history_32k_link
22594
23136
  );
22595
- const chatHistoryRaw = await readFile15(chatHistoryPath, "utf8");
23137
+ const chatHistoryRaw = await readFile16(chatHistoryPath, "utf8");
22596
23138
  const chatHistory = parseChatHistory(
22597
23139
  chatHistoryRaw,
22598
23140
  row.chat_history_32k_link
@@ -22725,12 +23267,12 @@ function parseCsv(raw, limit) {
22725
23267
  return rows;
22726
23268
  }
22727
23269
  async function resolveDatasetFilePath(datasetRoot, relativePath) {
22728
- const rootPath = path18.resolve(datasetRoot);
23270
+ const rootPath = path19.resolve(datasetRoot);
22729
23271
  const rootRealPath = await realpath4(rootPath);
22730
- const candidatePath = path18.resolve(rootPath, relativePath);
23272
+ const candidatePath = path19.resolve(rootPath, relativePath);
22731
23273
  const candidateRealPath = await realpath4(candidatePath);
22732
- const relativeToRoot = path18.relative(rootRealPath, candidateRealPath);
22733
- if (relativeToRoot.startsWith("..") || path18.isAbsolute(relativeToRoot)) {
23274
+ const relativeToRoot = path19.relative(rootRealPath, candidateRealPath);
23275
+ if (relativeToRoot.startsWith("..") || path19.isAbsolute(relativeToRoot)) {
22734
23276
  throw new Error(
22735
23277
  `PersonaMem-v2 dataset file reference "${relativePath}" must stay within datasetDir.`
22736
23278
  );
@@ -23058,8 +23600,8 @@ function applyLimit6(items, limit) {
23058
23600
 
23059
23601
  // src/benchmarks/published/membench/runner.ts
23060
23602
  import { randomUUID as randomUUID8 } from "crypto";
23061
- import { readFile as readFile16, readdir as readdir7 } from "fs/promises";
23062
- import path19 from "path";
23603
+ import { readFile as readFile17, readdir as readdir7 } from "fs/promises";
23604
+ import path20 from "path";
23063
23605
 
23064
23606
  // src/benchmarks/published/membench/fixture.ts
23065
23607
  var MEMBENCH_SMOKE_FIXTURE = [
@@ -23320,7 +23862,7 @@ async function loadDataset9(mode, datasetDir, limit) {
23320
23862
  let remainingLimit = normalizedLimit;
23321
23863
  for (const filename of filenames) {
23322
23864
  try {
23323
- const raw = await readFile16(path19.join(datasetDir, filename), "utf8");
23865
+ const raw = await readFile17(path20.join(datasetDir, filename), "utf8");
23324
23866
  const parsed = filename.endsWith(".jsonl") ? parseJsonlDataset(raw, filename) : parseJsonDataset(raw, filename);
23325
23867
  const limitedCases = remainingLimit === 0 ? [] : applyLimit7(parsed, remainingLimit);
23326
23868
  if (limitedCases.length > 0) {
@@ -24187,8 +24729,8 @@ function isPlainObject4(value) {
24187
24729
 
24188
24730
  // src/benchmarks/published/memoryagentbench/runner.ts
24189
24731
  import { randomUUID as randomUUID9 } from "crypto";
24190
- import { access, readFile as readFile17 } from "fs/promises";
24191
- import path20 from "path";
24732
+ import { access, readFile as readFile18 } from "fs/promises";
24733
+ import path21 from "path";
24192
24734
 
24193
24735
  // src/benchmarks/published/memoryagentbench/fixture.ts
24194
24736
  var MEMORY_AGENT_BENCH_SMOKE_FIXTURE = [
@@ -25210,7 +25752,7 @@ async function loadRecSysEntityMapping(datasetDir) {
25210
25752
  }
25211
25753
  let parsed;
25212
25754
  try {
25213
- parsed = JSON.parse(await readFile17(candidate, "utf8"));
25755
+ parsed = JSON.parse(await readFile18(candidate, "utf8"));
25214
25756
  } catch (error) {
25215
25757
  console.error(
25216
25758
  ` [WARN] MemoryAgentBench ReDial entity mapping ${candidate} is invalid JSON; trying the next candidate: ${error instanceof Error ? error.message : String(error)}`
@@ -25267,21 +25809,21 @@ function recsysEntityMappingCandidates(datasetDir) {
25267
25809
  if (!datasetDir) {
25268
25810
  return [];
25269
25811
  }
25270
- const absoluteDatasetDir = path20.resolve(datasetDir);
25812
+ const absoluteDatasetDir = path21.resolve(datasetDir);
25271
25813
  const roots = [
25272
25814
  absoluteDatasetDir,
25273
- path20.dirname(absoluteDatasetDir)
25815
+ path21.dirname(absoluteDatasetDir)
25274
25816
  ];
25275
25817
  const canonicalSuffixes = [
25276
- path20.join("processed_data", "Recsys_Redial", "entity2id.json"),
25277
- path20.join("Recsys_Redial", "entity2id.json")
25818
+ path21.join("processed_data", "Recsys_Redial", "entity2id.json"),
25819
+ path21.join("Recsys_Redial", "entity2id.json")
25278
25820
  ];
25279
25821
  const looseSuffixes = ["entity2id.json"];
25280
25822
  return [
25281
25823
  ...roots.flatMap(
25282
- (root) => canonicalSuffixes.map((suffix) => path20.join(root, suffix))
25824
+ (root) => canonicalSuffixes.map((suffix) => path21.join(root, suffix))
25283
25825
  ),
25284
- ...looseSuffixes.map((suffix) => path20.join(absoluteDatasetDir, suffix))
25826
+ ...looseSuffixes.map((suffix) => path21.join(absoluteDatasetDir, suffix))
25285
25827
  ];
25286
25828
  }
25287
25829
  async function fileExists(filePath) {
@@ -25318,7 +25860,7 @@ async function loadDataset10(mode, datasetDir, limit) {
25318
25860
  const datasetErrors = [];
25319
25861
  for (const filename of DATASET_BUNDLE_CANDIDATES) {
25320
25862
  const parsed = await tryReadDatasetFile(
25321
- path20.join(datasetDir, filename),
25863
+ path21.join(datasetDir, filename),
25322
25864
  filename,
25323
25865
  datasetErrors
25324
25866
  );
@@ -25335,7 +25877,7 @@ async function loadDataset10(mode, datasetDir, limit) {
25335
25877
  let splitData;
25336
25878
  for (const filename of splitConfig.candidates) {
25337
25879
  try {
25338
- splitData = await readDatasetFile(path20.join(datasetDir, filename), filename);
25880
+ splitData = await readDatasetFile(path21.join(datasetDir, filename), filename);
25339
25881
  break;
25340
25882
  } catch (error) {
25341
25883
  if (!isFileNotFoundError2(error)) {
@@ -25373,7 +25915,7 @@ async function loadDataset10(mode, datasetDir, limit) {
25373
25915
  return ensureDatasetItems(applyLimit8(MEMORY_AGENT_BENCH_SMOKE_FIXTURE, normalizedLimit));
25374
25916
  }
25375
25917
  async function readDatasetFile(filePath, filename) {
25376
- const raw = await readFile17(filePath, "utf8");
25918
+ const raw = await readFile18(filePath, "utf8");
25377
25919
  const parsed = filename.endsWith(".jsonl") ? parseJsonLines(raw, filename) : parseJsonArray(raw, filename);
25378
25920
  return parsed.map(
25379
25921
  (item, index) => parseMemoryAgentBenchItem(item, `${filename} item ${index + 1}`)
@@ -25983,8 +26525,8 @@ function loadCases(mode, limit) {
25983
26525
 
25984
26526
  // src/benchmarks/remnic/extraction-judge-calibration/runner.ts
25985
26527
  import { randomUUID as randomUUID11 } from "crypto";
25986
- import os5 from "os";
25987
- import path21 from "path";
26528
+ import os6 from "os";
26529
+ import path22 from "path";
25988
26530
  import {
25989
26531
  createVerdictCache,
25990
26532
  judgeFactDurability,
@@ -26094,8 +26636,8 @@ var extractionJudgeCalibrationDefinition = {
26094
26636
  async function runExtractionJudgeCalibrationBenchmark(options) {
26095
26637
  const cases = loadCases2(options.mode, options.limit);
26096
26638
  const config = parseConfig2({
26097
- memoryDir: path21.join(os5.tmpdir(), "remnic-bench-extraction-judge"),
26098
- workspaceDir: path21.join(os5.tmpdir(), "remnic-bench-extraction-judge-workspace"),
26639
+ memoryDir: path22.join(os6.tmpdir(), "remnic-bench-extraction-judge"),
26640
+ workspaceDir: path22.join(os6.tmpdir(), "remnic-bench-extraction-judge-workspace"),
26099
26641
  openaiApiKey: "bench-test-key",
26100
26642
  extractionJudgeEnabled: true,
26101
26643
  extractionJudgeBatchSize: 4,
@@ -26643,8 +27185,8 @@ function constantAggregate2(value) {
26643
27185
  }
26644
27186
 
26645
27187
  // src/benchmarks/remnic/entity-consolidation/runner.ts
26646
- import os6 from "os";
26647
- import path22 from "path";
27188
+ import os7 from "os";
27189
+ import path23 from "path";
26648
27190
  import { randomUUID as randomUUID13 } from "crypto";
26649
27191
  import { mkdtemp as mkdtemp4, rm as rm5 } from "fs/promises";
26650
27192
  import { StorageManager } from "@remnic/core";
@@ -26807,7 +27349,7 @@ function loadCases4(mode, limit) {
26807
27349
  return limited;
26808
27350
  }
26809
27351
  async function executeCase(sample) {
26810
- const tmpDir = await mkdtemp4(path22.join(os6.tmpdir(), "remnic-bench-entity-consolidation-"));
27352
+ const tmpDir = await mkdtemp4(path23.join(os7.tmpdir(), "remnic-bench-entity-consolidation-"));
26811
27353
  try {
26812
27354
  const storage = new StorageManager(tmpDir);
26813
27355
  await storage.ensureDirectories();
@@ -26986,9 +27528,9 @@ function parseNonNegativeInt(rawValue) {
26986
27528
 
26987
27529
  // src/benchmarks/remnic/page-versioning/runner.ts
26988
27530
  import { randomUUID as randomUUID14 } from "crypto";
26989
- import { mkdir as mkdir9, mkdtemp as mkdtemp5, readFile as readFile18, rm as rm6, writeFile as writeFile9 } from "fs/promises";
26990
- import os7 from "os";
26991
- import path23 from "path";
27531
+ import { mkdir as mkdir10, mkdtemp as mkdtemp5, readFile as readFile19, rm as rm6, writeFile as writeFile10 } from "fs/promises";
27532
+ import os8 from "os";
27533
+ import path24 from "path";
26992
27534
  import {
26993
27535
  createVersion,
26994
27536
  diffVersions,
@@ -27152,21 +27694,21 @@ function loadCases5(mode, limit) {
27152
27694
  return limited;
27153
27695
  }
27154
27696
  async function executeCase2(sample, dependencies) {
27155
- const tmpDir = await mkdtemp5(path23.join(os7.tmpdir(), "remnic-bench-page-versioning-"));
27697
+ const tmpDir = await mkdtemp5(path24.join(os8.tmpdir(), "remnic-bench-page-versioning-"));
27156
27698
  try {
27157
- const factsDir = path23.join(tmpDir, "facts");
27158
- const pagePath = path23.join(factsDir, `${sample.id}.md`);
27159
- await mkdir9(factsDir, { recursive: true });
27699
+ const factsDir = path24.join(tmpDir, "facts");
27700
+ const pagePath = path24.join(factsDir, `${sample.id}.md`);
27701
+ await mkdir10(factsDir, { recursive: true });
27160
27702
  const config = versioningConfig();
27161
27703
  switch (sample.scenario) {
27162
27704
  case "revert-flow": {
27163
- await writeFile9(pagePath, "original content", "utf-8");
27705
+ await writeFile10(pagePath, "original content", "utf-8");
27164
27706
  await dependencies.createVersion(pagePath, "original content", "write", config, void 0, void 0, tmpDir);
27165
- await writeFile9(pagePath, "modified content", "utf-8");
27707
+ await writeFile10(pagePath, "modified content", "utf-8");
27166
27708
  await dependencies.createVersion(pagePath, "modified content", "write", config, void 0, void 0, tmpDir);
27167
27709
  await dependencies.revertToVersion(pagePath, "1", config, void 0, tmpDir);
27168
27710
  const history = await dependencies.listVersions(pagePath, config, tmpDir);
27169
- const pageContent = await readFile18(pagePath, "utf-8");
27711
+ const pageContent = await readFile19(pagePath, "utf-8");
27170
27712
  const observed = await dependencies.getVersion(pagePath, "3", config, tmpDir);
27171
27713
  return {
27172
27714
  versionIds: history.versions.map((version) => version.versionId),
@@ -27179,11 +27721,11 @@ async function executeCase2(sample, dependencies) {
27179
27721
  const pruningConfig = versioningConfig({ maxVersionsPerPage: 2 });
27180
27722
  for (let index = 1; index <= 4; index += 1) {
27181
27723
  const content = `content v${index}`;
27182
- await writeFile9(pagePath, content, "utf-8");
27724
+ await writeFile10(pagePath, content, "utf-8");
27183
27725
  await dependencies.createVersion(pagePath, content, "write", pruningConfig, void 0, void 0, tmpDir);
27184
27726
  }
27185
27727
  const history = await dependencies.listVersions(pagePath, pruningConfig, tmpDir);
27186
- const pageContent = await readFile18(pagePath, "utf-8");
27728
+ const pageContent = await readFile19(pagePath, "utf-8");
27187
27729
  const prunedIds = [];
27188
27730
  for (const versionId of ["1", "2"]) {
27189
27731
  try {
@@ -27203,7 +27745,7 @@ async function executeCase2(sample, dependencies) {
27203
27745
  };
27204
27746
  }
27205
27747
  case "diff-output": {
27206
- await writeFile9(pagePath, "line 1\nline 2\nline 3", "utf-8");
27748
+ await writeFile10(pagePath, "line 1\nline 2\nline 3", "utf-8");
27207
27749
  await dependencies.createVersion(
27208
27750
  pagePath,
27209
27751
  "line 1\nline 2\nline 3",
@@ -27213,7 +27755,7 @@ async function executeCase2(sample, dependencies) {
27213
27755
  void 0,
27214
27756
  tmpDir
27215
27757
  );
27216
- await writeFile9(pagePath, "line 1\nline 2 changed\nline 3\nline 4", "utf-8");
27758
+ await writeFile10(pagePath, "line 1\nline 2 changed\nline 3\nline 4", "utf-8");
27217
27759
  await dependencies.createVersion(
27218
27760
  pagePath,
27219
27761
  "line 1\nline 2 changed\nline 3\nline 4",
@@ -27224,7 +27766,7 @@ async function executeCase2(sample, dependencies) {
27224
27766
  tmpDir
27225
27767
  );
27226
27768
  const history = await dependencies.listVersions(pagePath, config, tmpDir);
27227
- const pageContent = await readFile18(pagePath, "utf-8");
27769
+ const pageContent = await readFile19(pagePath, "utf-8");
27228
27770
  const diff = await dependencies.diffVersions(pagePath, "1", "2", config, tmpDir);
27229
27771
  const observedLines = normalizeDiffChangedLines(diff);
27230
27772
  return {
@@ -29510,8 +30052,8 @@ function loadCases9(mode, limit) {
29510
30052
  // src/benchmarks/remnic/procedural-recall/runner.ts
29511
30053
  import { randomUUID as randomUUID21 } from "crypto";
29512
30054
  import { mkdtemp as mkdtemp6, rm as rm7 } from "fs/promises";
29513
- import os8 from "os";
29514
- import path24 from "path";
30055
+ import os9 from "os";
30056
+ import path25 from "path";
29515
30057
  import {
29516
30058
  StorageManager as StorageManager2,
29517
30059
  parseConfig as parseConfig3,
@@ -29641,7 +30183,7 @@ async function runProceduralRecallBenchmark(options) {
29641
30183
  }
29642
30184
  for (const sample of e2eCases) {
29643
30185
  const startedAt = performance.now();
29644
- const dir = await mkdtemp6(path24.join(os8.tmpdir(), "remnic-bench-procedural-recall-"));
30186
+ const dir = await mkdtemp6(path25.join(os9.tmpdir(), "remnic-bench-procedural-recall-"));
29645
30187
  let section = null;
29646
30188
  try {
29647
30189
  const storage = new StorageManager2(dir);
@@ -29656,7 +30198,7 @@ ${body}`,
29656
30198
  );
29657
30199
  const config = parseConfig3({
29658
30200
  memoryDir: dir,
29659
- workspaceDir: path24.join(dir, "ws"),
30201
+ workspaceDir: path25.join(dir, "ws"),
29660
30202
  openaiApiKey: "bench-key",
29661
30203
  procedural: {
29662
30204
  enabled: sample.proceduralEnabled !== false,
@@ -29726,9 +30268,9 @@ ${body}`,
29726
30268
 
29727
30269
  // src/benchmarks/remnic/ingestion-entity-recall/runner.ts
29728
30270
  import { randomUUID as randomUUID22 } from "crypto";
29729
- import { mkdtemp as mkdtemp7, writeFile as writeFile10, rm as rm8, mkdir as mkdir10, realpath as realpath5 } from "fs/promises";
30271
+ import { mkdtemp as mkdtemp7, writeFile as writeFile11, rm as rm8, mkdir as mkdir11, realpath as realpath5 } from "fs/promises";
29730
30272
  import { tmpdir as tmpdir2 } from "os";
29731
- import path25 from "path";
30273
+ import path26 from "path";
29732
30274
 
29733
30275
  // src/ingestion-scorer.ts
29734
30276
  function normalize(value) {
@@ -30230,13 +30772,13 @@ async function runIngestionEntityRecallBenchmark(options) {
30230
30772
  throw new Error("ingestionAdapter is required for ingestion benchmarks");
30231
30773
  }
30232
30774
  const fixture = emailFixture.generate();
30233
- const fixtureDir = await mkdtemp7(path25.join(tmpdir2(), "bench-email-"));
30775
+ const fixtureDir = await mkdtemp7(path26.join(tmpdir2(), "bench-email-"));
30234
30776
  try {
30235
30777
  await options.ingestionAdapter.reset();
30236
30778
  for (const file of fixture.files) {
30237
- const filePath = path25.join(fixtureDir, file.relativePath);
30238
- await mkdir10(path25.dirname(filePath), { recursive: true });
30239
- await writeFile10(filePath, file.content, "utf8");
30779
+ const filePath = path26.join(fixtureDir, file.relativePath);
30780
+ await mkdir11(path26.dirname(filePath), { recursive: true });
30781
+ await writeFile11(filePath, file.content, "utf8");
30240
30782
  }
30241
30783
  const { result: ingestionLog, durationMs } = await timed(
30242
30784
  async () => options.ingestionAdapter.ingest(await realpath5(fixtureDir))
@@ -30363,9 +30905,9 @@ async function buildResult(options, tasks, totalLatencyMs) {
30363
30905
 
30364
30906
  // src/benchmarks/remnic/ingestion-schema-completeness/runner.ts
30365
30907
  import { randomUUID as randomUUID23 } from "crypto";
30366
- import { mkdtemp as mkdtemp8, writeFile as writeFile11, rm as rm9, mkdir as mkdir11, realpath as realpath6 } from "fs/promises";
30908
+ import { mkdtemp as mkdtemp8, writeFile as writeFile12, rm as rm9, mkdir as mkdir12, realpath as realpath6 } from "fs/promises";
30367
30909
  import { tmpdir as tmpdir3 } from "os";
30368
- import path26 from "path";
30910
+ import path27 from "path";
30369
30911
  var ingestionSchemaCompletenessDefinition = {
30370
30912
  id: "ingestion-schema-completeness",
30371
30913
  title: "Ingestion: Schema Completeness",
@@ -30384,13 +30926,13 @@ async function runIngestionSchemaCompletenessBenchmark(options) {
30384
30926
  throw new Error("ingestionAdapter is required for ingestion benchmarks");
30385
30927
  }
30386
30928
  const fixture = emailFixture.generate();
30387
- const fixtureDir = await mkdtemp8(path26.join(tmpdir3(), "bench-email-"));
30929
+ const fixtureDir = await mkdtemp8(path27.join(tmpdir3(), "bench-email-"));
30388
30930
  try {
30389
30931
  await options.ingestionAdapter.reset();
30390
30932
  for (const file of fixture.files) {
30391
- const filePath = path26.join(fixtureDir, file.relativePath);
30392
- await mkdir11(path26.dirname(filePath), { recursive: true });
30393
- await writeFile11(filePath, file.content, "utf8");
30933
+ const filePath = path27.join(fixtureDir, file.relativePath);
30934
+ await mkdir12(path27.dirname(filePath), { recursive: true });
30935
+ await writeFile12(filePath, file.content, "utf8");
30394
30936
  }
30395
30937
  const { result: ingestionLog, durationMs } = await timed(
30396
30938
  async () => options.ingestionAdapter.ingest(await realpath6(fixtureDir))
@@ -30536,9 +31078,9 @@ async function runIngestionSchemaCompletenessBenchmark(options) {
30536
31078
 
30537
31079
  // src/benchmarks/remnic/ingestion-backlink-f1/runner.ts
30538
31080
  import { randomUUID as randomUUID24 } from "crypto";
30539
- import { mkdtemp as mkdtemp9, writeFile as writeFile12, rm as rm10, mkdir as mkdir12, realpath as realpath7 } from "fs/promises";
31081
+ import { mkdtemp as mkdtemp9, writeFile as writeFile13, rm as rm10, mkdir as mkdir13, realpath as realpath7 } from "fs/promises";
30540
31082
  import { tmpdir as tmpdir4 } from "os";
30541
- import path27 from "path";
31083
+ import path28 from "path";
30542
31084
  var ingestionBacklinkF1Definition = {
30543
31085
  id: "ingestion-backlink-f1",
30544
31086
  title: "Ingestion: Backlink F1",
@@ -30557,13 +31099,13 @@ async function runIngestionBacklinkF1Benchmark(options) {
30557
31099
  throw new Error("ingestionAdapter is required for ingestion benchmarks");
30558
31100
  }
30559
31101
  const fixture = emailFixture.generate();
30560
- const fixtureDir = await mkdtemp9(path27.join(tmpdir4(), "bench-email-"));
31102
+ const fixtureDir = await mkdtemp9(path28.join(tmpdir4(), "bench-email-"));
30561
31103
  try {
30562
31104
  await options.ingestionAdapter.reset();
30563
31105
  for (const file of fixture.files) {
30564
- const filePath = path27.join(fixtureDir, file.relativePath);
30565
- await mkdir12(path27.dirname(filePath), { recursive: true });
30566
- await writeFile12(filePath, file.content, "utf8");
31106
+ const filePath = path28.join(fixtureDir, file.relativePath);
31107
+ await mkdir13(path28.dirname(filePath), { recursive: true });
31108
+ await writeFile13(filePath, file.content, "utf8");
30567
31109
  }
30568
31110
  const { result: ingestionLog, durationMs } = await timed(
30569
31111
  async () => options.ingestionAdapter.ingest(await realpath7(fixtureDir))
@@ -30637,9 +31179,9 @@ async function runIngestionBacklinkF1Benchmark(options) {
30637
31179
 
30638
31180
  // src/benchmarks/remnic/ingestion-setup-friction/runner.ts
30639
31181
  import { randomUUID as randomUUID25 } from "crypto";
30640
- import { mkdtemp as mkdtemp10, writeFile as writeFile13, rm as rm11, mkdir as mkdir13, realpath as realpath8 } from "fs/promises";
31182
+ import { mkdtemp as mkdtemp10, writeFile as writeFile14, rm as rm11, mkdir as mkdir14, realpath as realpath8 } from "fs/promises";
30641
31183
  import { tmpdir as tmpdir5 } from "os";
30642
- import path28 from "path";
31184
+ import path29 from "path";
30643
31185
  var INGESTION_SETUP_FRICTION_LOWER_IS_BETTER = /* @__PURE__ */ new Set(["setup_friction", "commands_count", "prompts_count", "errors_count"]);
30644
31186
  var ingestionSetupFrictionDefinition = {
30645
31187
  id: "ingestion-setup-friction",
@@ -30659,13 +31201,13 @@ async function runIngestionSetupFrictionBenchmark(options) {
30659
31201
  throw new Error("ingestionAdapter is required for ingestion benchmarks");
30660
31202
  }
30661
31203
  const fixture = emailFixture.generate();
30662
- const fixtureDir = await mkdtemp10(path28.join(tmpdir5(), "bench-friction-"));
31204
+ const fixtureDir = await mkdtemp10(path29.join(tmpdir5(), "bench-friction-"));
30663
31205
  try {
30664
31206
  await options.ingestionAdapter.reset();
30665
31207
  for (const file of fixture.files) {
30666
- const filePath = path28.join(fixtureDir, file.relativePath);
30667
- await mkdir13(path28.dirname(filePath), { recursive: true });
30668
- await writeFile13(filePath, file.content, "utf8");
31208
+ const filePath = path29.join(fixtureDir, file.relativePath);
31209
+ await mkdir14(path29.dirname(filePath), { recursive: true });
31210
+ await writeFile14(filePath, file.content, "utf8");
30669
31211
  }
30670
31212
  const { result: ingestionLog, durationMs } = await timed(
30671
31213
  async () => options.ingestionAdapter.ingest(await realpath8(fixtureDir))
@@ -30743,9 +31285,9 @@ async function runIngestionSetupFrictionBenchmark(options) {
30743
31285
 
30744
31286
  // src/benchmarks/remnic/ingestion-citation-accuracy/runner.ts
30745
31287
  import { randomUUID as randomUUID26 } from "crypto";
30746
- import { mkdtemp as mkdtemp11, writeFile as writeFile14, rm as rm12, mkdir as mkdir14, realpath as realpath9 } from "fs/promises";
31288
+ import { mkdtemp as mkdtemp11, writeFile as writeFile15, rm as rm12, mkdir as mkdir15, realpath as realpath9 } from "fs/promises";
30747
31289
  import { tmpdir as tmpdir6 } from "os";
30748
- import path29 from "path";
31290
+ import path30 from "path";
30749
31291
  var CITATION_SUPPORT_THRESHOLD = 0.72;
30750
31292
  var ingestionCitationAccuracyDefinition = {
30751
31293
  id: "ingestion-citation-accuracy",
@@ -30804,10 +31346,10 @@ function resolveCitedSources(sourceRefs, seeAlso, pageRef, sourceContentMap) {
30804
31346
  return "";
30805
31347
  }
30806
31348
  for (const ref of normalizedRefs) {
30807
- const refBase = path29.basename(ref).toLowerCase();
31349
+ const refBase = path30.basename(ref).toLowerCase();
30808
31350
  let matched = false;
30809
31351
  for (const [relativePath, content] of sourceContentMap) {
30810
- if (relativePath === ref || relativePath.endsWith(ref) || path29.basename(relativePath).toLowerCase() === refBase) {
31352
+ if (relativePath === ref || relativePath.endsWith(ref) || path30.basename(relativePath).toLowerCase() === refBase) {
30811
31353
  resolved.push(content);
30812
31354
  matched = true;
30813
31355
  break;
@@ -30823,9 +31365,9 @@ function resolveCitedSources(sourceRefs, seeAlso, pageRef, sourceContentMap) {
30823
31365
  if (normalizedRefs.length > 0) {
30824
31366
  return "";
30825
31367
  }
30826
- const pageBase = path29.basename(pageRef).toLowerCase();
31368
+ const pageBase = path30.basename(pageRef).toLowerCase();
30827
31369
  for (const [relativePath, content] of sourceContentMap) {
30828
- if (path29.basename(relativePath).toLowerCase() === pageBase) {
31370
+ if (path30.basename(relativePath).toLowerCase() === pageBase) {
30829
31371
  return content;
30830
31372
  }
30831
31373
  }
@@ -30836,13 +31378,13 @@ async function runIngestionCitationAccuracyBenchmark(options) {
30836
31378
  throw new Error("ingestionAdapter is required for ingestion benchmarks");
30837
31379
  }
30838
31380
  const fixture = emailFixture.generate();
30839
- const fixtureDir = await mkdtemp11(path29.join(tmpdir6(), "bench-citation-"));
31381
+ const fixtureDir = await mkdtemp11(path30.join(tmpdir6(), "bench-citation-"));
30840
31382
  try {
30841
31383
  await options.ingestionAdapter.reset();
30842
31384
  for (const file of fixture.files) {
30843
- const filePath = path29.join(fixtureDir, file.relativePath);
30844
- await mkdir14(path29.dirname(filePath), { recursive: true });
30845
- await writeFile14(filePath, file.content, "utf8");
31385
+ const filePath = path30.join(fixtureDir, file.relativePath);
31386
+ await mkdir15(path30.dirname(filePath), { recursive: true });
31387
+ await writeFile15(filePath, file.content, "utf8");
30846
31388
  }
30847
31389
  const benchmarkStart = performance.now();
30848
31390
  const { result: ingestionLog, durationMs: ingestionDurationMs } = await timed(
@@ -31227,7 +31769,7 @@ var ASSISTANT_MORNING_BRIEF_SMOKE_SCENARIOS = ASSISTANT_MORNING_BRIEF_SCENARIOS.
31227
31769
 
31228
31770
  // src/benchmarks/remnic/_assistant-common/runner.ts
31229
31771
  import { randomUUID as randomUUID27 } from "crypto";
31230
- import path31 from "path";
31772
+ import path32 from "path";
31231
31773
 
31232
31774
  // src/run-seeds.ts
31233
31775
  function buildBenchmarkRunSeeds(runCount, baseSeed) {
@@ -31319,7 +31861,7 @@ function pairedDeltaConfidenceInterval(candidateValues, baselineValues, options
31319
31861
  // src/judges/sealed-rubric.ts
31320
31862
  import { createHash as createHash8 } from "crypto";
31321
31863
  import { appendFileSync, mkdirSync } from "fs";
31322
- import path30 from "path";
31864
+ import path31 from "path";
31323
31865
 
31324
31866
  // src/judges/sealed-prompts/assistant-rubric-v1.ts
31325
31867
  var ASSISTANT_RUBRIC_V1 = `# Assistant rubric v1 (sealed)
@@ -31599,7 +32141,7 @@ function createSpotCheckFileLogger(options) {
31599
32141
  return { log() {
31600
32142
  } };
31601
32143
  }
31602
- const logPath = path30.join(directory, `${runId}.jsonl`);
32144
+ const logPath = path31.join(directory, `${runId}.jsonl`);
31603
32145
  let written = 0;
31604
32146
  let warnedOnWriteFailure = false;
31605
32147
  const cap = typeof sampleSize === "number" && sampleSize > 0 ? sampleSize : 5;
@@ -31688,7 +32230,7 @@ async function runAssistantBenchmark(definition, scenarios, resolved, runnerOpti
31688
32230
  const runId = buildRunId(definition.id);
31689
32231
  const spotCheckLogger = createSpotCheckFileLogger({
31690
32232
  runId,
31691
- directory: runnerOptions.spotCheckDir ?? path31.join(process.cwd(), "benchmarks", "results", "spot-checks"),
32233
+ directory: runnerOptions.spotCheckDir ?? path32.join(process.cwd(), "benchmarks", "results", "spot-checks"),
31692
32234
  sampleRate: 0.35,
31693
32235
  sampleSize: 5
31694
32236
  });
@@ -32337,9 +32879,9 @@ async function runAssistantSynthesisBenchmark(options) {
32337
32879
 
32338
32880
  // src/benchmarks/remnic/buffer-surprise-trigger/runner.ts
32339
32881
  import { randomUUID as randomUUID28 } from "crypto";
32340
- import path32 from "path";
32341
- import os9 from "os";
32342
- import { mkdir as mkdir15, rm as rm13 } from "fs/promises";
32882
+ import path33 from "path";
32883
+ import os10 from "os";
32884
+ import { mkdir as mkdir16, rm as rm13 } from "fs/promises";
32343
32885
  import {
32344
32886
  SmartBuffer,
32345
32887
  computeSurprise,
@@ -32568,11 +33110,11 @@ function hasExplicitTopicPivotCue(text) {
32568
33110
  }
32569
33111
  async function runBufferSurpriseTriggerBenchmark(options) {
32570
33112
  const cases = loadCases10(options.mode, options.limit);
32571
- const tmpRoot = path32.join(
32572
- os9.tmpdir(),
33113
+ const tmpRoot = path33.join(
33114
+ os10.tmpdir(),
32573
33115
  `remnic-bench-buffer-surprise-${randomUUID28()}`
32574
33116
  );
32575
- await mkdir15(tmpRoot, { recursive: true });
33117
+ await mkdir16(tmpRoot, { recursive: true });
32576
33118
  const tasks = [];
32577
33119
  const startedAt = performance.now();
32578
33120
  try {
@@ -32637,12 +33179,12 @@ async function runBufferSurpriseTriggerBenchmark(options) {
32637
33179
  };
32638
33180
  }
32639
33181
  async function runSingleCase(caseDef, options) {
32640
- const memoryDir = path32.join(
33182
+ const memoryDir = path33.join(
32641
33183
  options.tmpRoot,
32642
33184
  `${caseDef.id}-${options.label}`
32643
33185
  );
32644
- const workspaceDir = path32.join(memoryDir, "workspace");
32645
- await mkdir15(workspaceDir, { recursive: true });
33186
+ const workspaceDir = path33.join(memoryDir, "workspace");
33187
+ await mkdir16(workspaceDir, { recursive: true });
32646
33188
  const config = parseConfig4({
32647
33189
  memoryDir,
32648
33190
  workspaceDir,
@@ -34904,8 +35446,8 @@ async function runMemCorrectBenchmark(options) {
34904
35446
 
34905
35447
  // src/benchmarks/remnic/bounded-memory-contracts/runner.ts
34906
35448
  import { randomUUID as randomUUID32 } from "crypto";
34907
- import { mkdir as mkdir16, writeFile as writeFile15 } from "fs/promises";
34908
- import path33 from "path";
35449
+ import { mkdir as mkdir17, writeFile as writeFile16 } from "fs/promises";
35450
+ import path34 from "path";
34909
35451
 
34910
35452
  // src/benchmarks/remnic/bounded-memory-contracts/fixture.ts
34911
35453
  import { createHash as createHash10 } from "crypto";
@@ -36137,24 +36679,24 @@ async function runBoundedMemoryContractsBenchmark(options) {
36137
36679
  };
36138
36680
  }
36139
36681
  async function writeArtifacts(outputDir, byCondition, conditionAggregates, tasks) {
36140
- const root = path33.resolve(outputDir);
36141
- await mkdir16(path33.join(root, "conditions"), { recursive: true });
36142
- await mkdir16(path33.join(root, "prompts"), { recursive: true });
36143
- await mkdir16(path33.join(root, "retrieval"), { recursive: true });
36144
- await mkdir16(path33.join(root, "scores"), { recursive: true });
36682
+ const root = path34.resolve(outputDir);
36683
+ await mkdir17(path34.join(root, "conditions"), { recursive: true });
36684
+ await mkdir17(path34.join(root, "prompts"), { recursive: true });
36685
+ await mkdir17(path34.join(root, "retrieval"), { recursive: true });
36686
+ await mkdir17(path34.join(root, "scores"), { recursive: true });
36145
36687
  const csvRows = [
36146
36688
  "task_id,condition,family,scope,task_success,should_ask_accuracy,relevant_memory_recall,stale_memory_harm_rate,wrong_scope_retrieval_rate,supersession_respected_rate,citation_coverage,memory_tokens_injected,retrieved_item_count,compression_ratio_vs_raw_transcript"
36147
36689
  ];
36148
36690
  for (const condition of BOUNDED_MEMORY_CONDITIONS) {
36149
36691
  const results = byCondition.get(condition);
36150
- const condDir = path33.join(root, "conditions", condition);
36151
- await mkdir16(condDir, { recursive: true });
36692
+ const condDir = path34.join(root, "conditions", condition);
36693
+ await mkdir17(condDir, { recursive: true });
36152
36694
  for (const { task, pack, decision } of results) {
36153
36695
  const scores = scoreTaskPair(task, pack, decision);
36154
36696
  const promptMd = renderPromptPack(task, condition, pack);
36155
- const promptPath = path33.join(root, "prompts", `${task.id}.${condition}.md`);
36156
- await mkdir16(path33.dirname(promptPath), { recursive: true });
36157
- await writeFile15(promptPath, promptMd, "utf8");
36697
+ const promptPath = path34.join(root, "prompts", `${task.id}.${condition}.md`);
36698
+ await mkdir17(path34.dirname(promptPath), { recursive: true });
36699
+ await writeFile16(promptPath, promptMd, "utf8");
36158
36700
  const retrievalJson = `${JSON.stringify(
36159
36701
  {
36160
36702
  taskId: task.id,
@@ -36177,8 +36719,8 @@ async function writeArtifacts(outputDir, byCondition, conditionAggregates, tasks
36177
36719
  2
36178
36720
  )}
36179
36721
  `;
36180
- const retrievalPath = path33.join(root, "retrieval", `${task.id}.${condition}.json`);
36181
- await writeFile15(retrievalPath, retrievalJson, "utf8");
36722
+ const retrievalPath = path34.join(root, "retrieval", `${task.id}.${condition}.json`);
36723
+ await writeFile16(retrievalPath, retrievalJson, "utf8");
36182
36724
  csvRows.push(
36183
36725
  [
36184
36726
  task.id,
@@ -36198,24 +36740,24 @@ async function writeArtifacts(outputDir, byCondition, conditionAggregates, tasks
36198
36740
  ].join(",")
36199
36741
  );
36200
36742
  }
36201
- await writeFile15(
36202
- path33.join(condDir, "summary.json"),
36743
+ await writeFile16(
36744
+ path34.join(condDir, "summary.json"),
36203
36745
  `${JSON.stringify(conditionAggregates[condition], null, 2)}
36204
36746
  `,
36205
36747
  "utf8"
36206
36748
  );
36207
36749
  }
36208
- await writeFile15(path33.join(root, "scores", "per-task.csv"), `${csvRows.join("\n")}
36750
+ await writeFile16(path34.join(root, "scores", "per-task.csv"), `${csvRows.join("\n")}
36209
36751
  `, "utf8");
36210
- await writeFile15(
36211
- path33.join(root, "scores", "aggregate.json"),
36752
+ await writeFile16(
36753
+ path34.join(root, "scores", "aggregate.json"),
36212
36754
  `${JSON.stringify(conditionAggregates, null, 2)}
36213
36755
  `,
36214
36756
  "utf8"
36215
36757
  );
36216
36758
  const report = renderReportMarkdown(tasks, conditionAggregates);
36217
- await writeFile15(path33.join(root, "report.md"), report, "utf8");
36218
- return path33.join(root, "report.md");
36759
+ await writeFile16(path34.join(root, "report.md"), report, "utf8");
36760
+ return path34.join(root, "report.md");
36219
36761
  }
36220
36762
  function renderPromptPack(task, condition, pack) {
36221
36763
  const lines = [];
@@ -36440,8 +36982,8 @@ function finalizeBenchmarkResultConfig(result, options) {
36440
36982
  }
36441
36983
 
36442
36984
  // src/benchmark.ts
36443
- var DEFAULT_BASELINE_PATH = path34.join(process.cwd(), "benchmarks", "baseline.json");
36444
- var DEFAULT_REPORT_PATH = path34.join(process.cwd(), "benchmarks", "report.json");
36985
+ var DEFAULT_BASELINE_PATH = path35.join(process.cwd(), "benchmarks", "baseline.json");
36986
+ var DEFAULT_REPORT_PATH = path35.join(process.cwd(), "benchmarks", "report.json");
36445
36987
  var BASELINE_VERSION = 1;
36446
36988
  var DEFAULT_TOLERANCE = 10;
36447
36989
  var DEFAULT_FULL_RUN_COUNT = 5;
@@ -36519,7 +37061,7 @@ async function runBenchmark(benchmarkId, options) {
36519
37061
  if (!willWrapPrimary && !willWrapCross) {
36520
37062
  return void 0;
36521
37063
  }
36522
- const cacheDir = options.judgeCacheDir ? path34.resolve(expandTildePath3(options.judgeCacheDir)) : options.outputDir ? path34.join(path34.resolve(expandTildePath3(options.outputDir)), "judge-cache") : void 0;
37064
+ const cacheDir = options.judgeCacheDir ? path35.resolve(expandTildePath3(options.judgeCacheDir)) : options.outputDir ? path35.join(path35.resolve(expandTildePath3(options.outputDir)), "judge-cache") : void 0;
36523
37065
  if (cacheDir === void 0) {
36524
37066
  return void 0;
36525
37067
  }
@@ -36718,7 +37260,7 @@ function loadBaseline(baselinePath) {
36718
37260
  return raw;
36719
37261
  }
36720
37262
  function saveBaseline(baselinePath, baseline) {
36721
- fs2.mkdirSync(path34.dirname(baselinePath), { recursive: true });
37263
+ fs2.mkdirSync(path35.dirname(baselinePath), { recursive: true });
36722
37264
  fs2.writeFileSync(baselinePath, `${JSON.stringify(baseline, null, 2)}
36723
37265
  `);
36724
37266
  }
@@ -36948,7 +37490,7 @@ function generateReport(results, reportPath) {
36948
37490
  totalDurationMs: results.reduce((sum, result) => sum + result.totalDurationMs, 0)
36949
37491
  };
36950
37492
  if (reportPath) {
36951
- fs2.mkdirSync(path34.dirname(reportPath), { recursive: true });
37493
+ fs2.mkdirSync(path35.dirname(reportPath), { recursive: true });
36952
37494
  fs2.writeFileSync(reportPath, `${JSON.stringify(report, null, 2)}
36953
37495
  `);
36954
37496
  }
@@ -37363,7 +37905,7 @@ function formatSignedScore(value) {
37363
37905
  }
37364
37906
 
37365
37907
  // src/integrity/sealed-qrels.ts
37366
- import { readFile as readFile19 } from "fs/promises";
37908
+ import { readFile as readFile20 } from "fs/promises";
37367
37909
  function isSealedQrelsArtifact(value) {
37368
37910
  if (!value || typeof value !== "object") {
37369
37911
  return false;
@@ -37433,7 +37975,7 @@ function parseSealedQrels(raw, options = {}) {
37433
37975
  };
37434
37976
  }
37435
37977
  async function loadSealedQrels(filePath, options = {}) {
37436
- const raw = await readFile19(filePath, "utf8");
37978
+ const raw = await readFile20(filePath, "utf8");
37437
37979
  return parseSealedQrels(raw, options);
37438
37980
  }
37439
37981
  function serializeSealedQrels(artifact) {
@@ -37553,7 +38095,7 @@ function selectFixtureVariant(variants, seed) {
37553
38095
  }
37554
38096
 
37555
38097
  // src/benchmarks/custom/loader.ts
37556
- import { readFile as readFile20 } from "fs/promises";
38098
+ import { readFile as readFile21 } from "fs/promises";
37557
38099
  import { parse as parseYaml } from "yaml";
37558
38100
  var CUSTOM_SCORING_VALUES = /* @__PURE__ */ new Set([
37559
38101
  "exact_match",
@@ -37573,7 +38115,7 @@ function parseCustomBenchmark(source) {
37573
38115
  async function loadCustomBenchmarkFile(filePath) {
37574
38116
  let source;
37575
38117
  try {
37576
- source = await readFile20(filePath, "utf8");
38118
+ source = await readFile21(filePath, "utf8");
37577
38119
  } catch (error) {
37578
38120
  throw new Error(
37579
38121
  `Failed to read custom benchmark file ${filePath}: ${formatError(error)}`
@@ -37681,7 +38223,7 @@ function formatError(error) {
37681
38223
 
37682
38224
  // src/benchmarks/custom/runner.ts
37683
38225
  import { randomUUID as randomUUID33 } from "crypto";
37684
- import path35 from "path";
38226
+ import path36 from "path";
37685
38227
  import { expandTildePath as expandTildePath4 } from "@remnic/core";
37686
38228
  async function runCustomBenchmarkFile(filePath, options) {
37687
38229
  const spec = await loadCustomBenchmarkFile(filePath);
@@ -37694,7 +38236,7 @@ async function runCustomBenchmarkFile(filePath, options) {
37694
38236
  let cacheRestore;
37695
38237
  let cacheCounters;
37696
38238
  if (spec.scoring === "llm_judge" && runOptions.system.judge !== void 0 && !runOptions.noJudgeCache && (runOptions.judgeProvider ?? null) !== null) {
37697
- const cacheDir = runOptions.judgeCacheDir ? path35.resolve(expandTildePath4(runOptions.judgeCacheDir)) : runOptions.outputDir ? path35.join(path35.resolve(expandTildePath4(runOptions.outputDir)), "judge-cache") : void 0;
38239
+ const cacheDir = runOptions.judgeCacheDir ? path36.resolve(expandTildePath4(runOptions.judgeCacheDir)) : runOptions.outputDir ? path36.join(path36.resolve(expandTildePath4(runOptions.outputDir)), "judge-cache") : void 0;
37698
38240
  if (cacheDir !== void 0) {
37699
38241
  const originalJudge = runOptions.system.judge;
37700
38242
  const wrapped = wrapJudgeWithCache({
@@ -37895,7 +38437,7 @@ async function scoreTask(scoring, options, question, actual, expected) {
37895
38437
  }
37896
38438
  }
37897
38439
  function createCustomBenchmarkDefinition(benchmark, filePath) {
37898
- const id = `custom:${slugify(path35.basename(filePath, path35.extname(filePath)) || benchmark.name)}`;
38440
+ const id = `custom:${slugify(path36.basename(filePath, path36.extname(filePath)) || benchmark.name)}`;
37899
38441
  return {
37900
38442
  id,
37901
38443
  title: benchmark.name,
@@ -38766,8 +39308,8 @@ var chatFixture = {
38766
39308
 
38767
39309
  // src/judges/calibration-slice.ts
38768
39310
  import { createHash as createHash12, randomBytes as randomBytes3 } from "crypto";
38769
- import { mkdir as mkdir17, readFile as readFile21, rename as rename3, unlink as unlink3, writeFile as writeFile16 } from "fs/promises";
38770
- import path36 from "path";
39311
+ import { mkdir as mkdir18, readFile as readFile22, rename as rename4, unlink as unlink4, writeFile as writeFile17 } from "fs/promises";
39312
+ import path37 from "path";
38771
39313
 
38772
39314
  // src/judges/cohen-kappa.ts
38773
39315
  var DEFAULT_KAPPA_BOOTSTRAP_SAMPLES = 2e3;
@@ -38995,7 +39537,7 @@ function hashCalibrationAnswerSet(answers) {
38995
39537
  ]))).digest("hex");
38996
39538
  }
38997
39539
  async function writeJudgeCalibrationState(result, calibrationDir, identities, provenance) {
38998
- await mkdir17(calibrationDir, { recursive: true });
39540
+ await mkdir18(calibrationDir, { recursive: true });
38999
39541
  const state = {
39000
39542
  kappa: result.kappa,
39001
39543
  sampleSize: result.sampleSize,
@@ -39008,23 +39550,23 @@ async function writeJudgeCalibrationState(result, calibrationDir, identities, pr
39008
39550
  ...provenance ? provenance : {},
39009
39551
  ...identities ? identities : {}
39010
39552
  };
39011
- const filePath = path36.join(calibrationDir, `${sanitizeCalibrationSegment(result.benchmarkId)}.json`);
39553
+ const filePath = path37.join(calibrationDir, `${sanitizeCalibrationSegment(result.benchmarkId)}.json`);
39012
39554
  const tempPath = `${filePath}.${randomBytes3(6).toString("hex")}.tmp`;
39013
- await writeFile16(tempPath, `${JSON.stringify(state, null, 2)}
39555
+ await writeFile17(tempPath, `${JSON.stringify(state, null, 2)}
39014
39556
  `, "utf8");
39015
39557
  try {
39016
- await rename3(tempPath, filePath);
39558
+ await rename4(tempPath, filePath);
39017
39559
  } catch (error) {
39018
- await unlink3(tempPath).catch(() => void 0);
39560
+ await unlink4(tempPath).catch(() => void 0);
39019
39561
  throw error;
39020
39562
  }
39021
39563
  return filePath;
39022
39564
  }
39023
39565
  async function loadJudgeCalibrationState(benchmarkId, calibrationDir) {
39024
- const filePath = path36.join(calibrationDir, `${sanitizeCalibrationSegment(benchmarkId)}.json`);
39566
+ const filePath = path37.join(calibrationDir, `${sanitizeCalibrationSegment(benchmarkId)}.json`);
39025
39567
  let raw;
39026
39568
  try {
39027
- raw = await readFile21(filePath, "utf8");
39569
+ raw = await readFile22(filePath, "utf8");
39028
39570
  } catch {
39029
39571
  return void 0;
39030
39572
  }
@@ -39108,9 +39650,9 @@ function sanitizeCalibrationSegment(value) {
39108
39650
  }
39109
39651
 
39110
39652
  // src/benchmarks/remnic/procedural-recall/ablation.ts
39111
- import { mkdir as mkdir18, mkdtemp as mkdtemp12, rm as rm14, writeFile as writeFile17, readFile as readFile22 } from "fs/promises";
39112
- import os10 from "os";
39113
- import path37 from "path";
39653
+ import { mkdir as mkdir19, mkdtemp as mkdtemp12, rm as rm14, writeFile as writeFile18, readFile as readFile23 } from "fs/promises";
39654
+ import os11 from "os";
39655
+ import path38 from "path";
39114
39656
  import {
39115
39657
  StorageManager as StorageManager3,
39116
39658
  parseConfig as parseConfig5,
@@ -39141,7 +39683,7 @@ async function runSide(scenarios, proceduralEnabled) {
39141
39683
  const observed = [];
39142
39684
  for (const scenario of scenarios) {
39143
39685
  const dir = await mkdtemp12(
39144
- path37.join(os10.tmpdir(), "remnic-bench-proc-ablation-")
39686
+ path38.join(os11.tmpdir(), "remnic-bench-proc-ablation-")
39145
39687
  );
39146
39688
  try {
39147
39689
  const storage = new StorageManager3(dir);
@@ -39156,7 +39698,7 @@ ${body}`,
39156
39698
  );
39157
39699
  const config = parseConfig5({
39158
39700
  memoryDir: dir,
39159
- workspaceDir: path37.join(dir, "ws"),
39701
+ workspaceDir: path38.join(dir, "ws"),
39160
39702
  openaiApiKey: "bench-key",
39161
39703
  procedural: {
39162
39704
  enabled: proceduralEnabled,
@@ -39231,7 +39773,7 @@ async function runProceduralAblation(options) {
39231
39773
  };
39232
39774
  }
39233
39775
  async function loadAblationFixture(fixturePath) {
39234
- const raw = await readFile22(fixturePath, "utf8");
39776
+ const raw = await readFile23(fixturePath, "utf8");
39235
39777
  let parsed;
39236
39778
  try {
39237
39779
  parsed = JSON.parse(raw);
@@ -39327,9 +39869,9 @@ async function runProceduralAblationCli(args) {
39327
39869
  random: args.random,
39328
39870
  seed: args.seed
39329
39871
  });
39330
- const outDir = path37.dirname(path37.resolve(args.outPath));
39331
- await mkdir18(outDir, { recursive: true });
39332
- await writeFile17(args.outPath, JSON.stringify(artifact, null, 2) + "\n", "utf8");
39872
+ const outDir = path38.dirname(path38.resolve(args.outPath));
39873
+ await mkdir19(outDir, { recursive: true });
39874
+ await writeFile18(args.outPath, JSON.stringify(artifact, null, 2) + "\n", "utf8");
39333
39875
  return artifact;
39334
39876
  }
39335
39877
 
@@ -40570,8 +41112,8 @@ import { performance as performance2 } from "perf_hooks";
40570
41112
  import { mkdtemp as mkdtemp13, rm as rm15 } from "fs/promises";
40571
41113
  import { statSync } from "fs";
40572
41114
  import { tmpdir as tmpdir7 } from "os";
40573
- import path38 from "path";
40574
- import os11 from "os";
41115
+ import path39 from "path";
41116
+ import os12 from "os";
40575
41117
  import {
40576
41118
  GraphStore
40577
41119
  } from "@remnic/coding-graph";
@@ -40597,14 +41139,14 @@ var CODING_GRAPH_BENCH_SCHEMA_VERSION = 2;
40597
41139
 
40598
41140
  // src/coding-graph/harness.ts
40599
41141
  function captureMachineFingerprint() {
40600
- const cpus = os11.cpus();
41142
+ const cpus = os12.cpus();
40601
41143
  return {
40602
41144
  arch: process.arch,
40603
41145
  platform: process.platform,
40604
41146
  nodeVersion: process.version,
40605
41147
  cpuModel: cpus.length > 0 ? cpus[0].model : null,
40606
41148
  cpuCores: cpus.length,
40607
- totalMemoryMb: Math.round(os11.totalmem() / (1024 * 1024))
41149
+ totalMemoryMb: Math.round(os12.totalmem() / (1024 * 1024))
40608
41150
  };
40609
41151
  }
40610
41152
  function percentile3(sorted, p) {
@@ -40667,15 +41209,15 @@ async function runCodingGraphBenchmark(config = {}) {
40667
41209
  const sampleRss = () => {
40668
41210
  peakRss = Math.max(peakRss, process.memoryUsage().rss);
40669
41211
  };
40670
- const dir = await mkdtemp13(path38.join(tmpdir7(), "coding-graph-bench-"));
40671
- const dbPath = path38.join(dir, "bench.sqlite");
41212
+ const dir = await mkdtemp13(path39.join(tmpdir7(), "coding-graph-bench-"));
41213
+ const dbPath = path39.join(dir, "bench.sqlite");
40672
41214
  try {
40673
41215
  const store = await GraphStore.open({ dbPath });
40674
41216
  try {
40675
41217
  const FULL_INDEX_SAMPLES = 3;
40676
41218
  const fullIndexSamples = [];
40677
41219
  for (let s = 0; s < FULL_INDEX_SAMPLES; s++) {
40678
- const sampleStore = s === 0 ? store : await GraphStore.open({ dbPath: path38.join(dir, `bench-warm-${s}.sqlite`) });
41220
+ const sampleStore = s === 0 ? store : await GraphStore.open({ dbPath: path39.join(dir, `bench-warm-${s}.sqlite`) });
40679
41221
  const fi = await timeAsync(() => sampleStore.upsertFileBatch(storeFiles));
40680
41222
  if (!fi.result.ok) {
40681
41223
  if (sampleStore !== store) await sampleStore.close();
@@ -41067,6 +41609,7 @@ export {
41067
41609
  SEALED_PROMPT_REGISTRY,
41068
41610
  SINGLE_FLAG_ABLATION_MATRIX,
41069
41611
  SYNTHETIC_MEMORIES,
41612
+ StructuredJudgeError,
41070
41613
  ZepMemCorrectAdapter,
41071
41614
  addContaminationEntry,
41072
41615
  aggregateTaskScores,
@@ -41140,6 +41683,7 @@ export {
41140
41683
  createResponderFromProvider,
41141
41684
  createSeededRng,
41142
41685
  createSpotCheckFileLogger,
41686
+ createStructuredBenchJudge,
41143
41687
  createStructuredJudgeFromProvider,
41144
41688
  createSyntheticEmailIngestionAdapter,
41145
41689
  createSyntheticTarget,
@@ -41177,6 +41721,7 @@ export {
41177
41721
  isContaminationManifest,
41178
41722
  isSealedQrelsArtifact,
41179
41723
  isSha256Hex,
41724
+ isStructuredJudgeProvider,
41180
41725
  judgeMemCorrectCorrectionAcceptance,
41181
41726
  judgeMemCorrectStaleMemoryHarm,
41182
41727
  linkMatches,