import {
  listJsonFiles,
  listNamedFiles,
  readJsonFile
} from "./chunk-LPSF4OQH.js";

// src/evals.ts
import path from "path";
import { cp, mkdir, rm, stat, writeFile } from "fs/promises";
function isRecord(value) {
  return typeof value === "object" && value !== null && !Array.isArray(value);
}
function assertString(value, field) {
  if (typeof value !== "string" || value.trim().length === 0) {
    throw new Error(`${field} must be a non-empty string`);
  }
  return value.trim();
}
function optionalStringArray(value, field) {
  if (value === void 0) return void 0;
  if (!Array.isArray(value)) {
    throw new Error(`${field} must be an array of strings`);
  }
  const out = value.filter((item) => typeof item === "string").map((item) => item.trim()).filter((item) => item.length > 0);
  if (out.length !== value.length) {
    throw new Error(`${field} must be an array of non-empty strings`);
  }
  return out;
}
function resolveEvalStoreDir(memoryDir, overrideDir) {
  if (typeof overrideDir === "string" && overrideDir.trim().length > 0) {
    return overrideDir.trim();
  }
  return path.join(memoryDir, "state", "evals");
}
function assertSafePathSegment(value, field) {
  if (value === "." || value === ".." || value.includes("/") || value.includes("\\")) {
    throw new Error(`${field} must be a safe path segment`);
  }
  return value;
}
function assertSafeBenchmarkId(benchmarkId) {
  return assertSafePathSegment(benchmarkId, "benchmarkId");
}
function validateEvalBenchmarkManifest(raw, options) {
  if (!isRecord(raw)) throw new Error("benchmark manifest must be an object");
  if (raw.schemaVersion !== 1) throw new Error("schemaVersion must be 1");
  if (!Array.isArray(raw.cases)) throw new Error("cases must be an array");
  const benchmarkTypeRaw = typeof raw.benchmarkType === "string" && raw.benchmarkType.trim().length > 0 ? raw.benchmarkType.trim() : "standard";
  if (!["standard", "memory-red-team"].includes(benchmarkTypeRaw)) {
    throw new Error("benchmarkType must be one of standard|memory-red-team");
  }
  const cases = raw.cases.map((item, index) => {
    if (!isRecord(item)) throw new Error(`cases[${index}] must be an object`);
    return {
      id: assertString(item.id, `cases[${index}].id`),
      prompt: assertString(item.prompt, `cases[${index}].prompt`),
      expectedSignals: optionalStringArray(item.expectedSignals, `cases[${index}].expectedSignals`),
      notes: typeof item.notes === "string" && item.notes.trim().length > 0 ? item.notes.trim() : void 0
    };
  });
  const benchmarkType = benchmarkTypeRaw;
  if (benchmarkType === "memory-red-team" && options?.memoryRedTeamBenchEnabled !== true) {
    throw new Error("memory-red-team benchmark packs require memoryRedTeamBenchEnabled");
  }
  const attackClass = typeof raw.attackClass === "string" && raw.attackClass.trim().length > 0 ? raw.attackClass.trim() : void 0;
  const targetSurface = typeof raw.targetSurface === "string" && raw.targetSurface.trim().length > 0 ? raw.targetSurface.trim() : void 0;
  if (benchmarkType === "memory-red-team" && attackClass === void 0) {
    throw new Error("attackClass must be a non-empty string");
  }
  if (benchmarkType === "memory-red-team" && targetSurface === void 0) {
    throw new Error("targetSurface must be a non-empty string");
  }
  return {
    schemaVersion: 1,
    benchmarkId: assertString(raw.benchmarkId, "benchmarkId"),
    benchmarkType,
    title: assertString(raw.title, "title"),
    description: typeof raw.description === "string" && raw.description.trim().length > 0 ? raw.description.trim() : void 0,
    tags: optionalStringArray(raw.tags, "tags"),
    sourceLinks: optionalStringArray(raw.sourceLinks, "sourceLinks"),
    attackClass,
    targetSurface,
    cases
  };
}
function validateEvalRunSummary(raw) {
  if (!isRecord(raw)) throw new Error("eval run summary must be an object");
  if (raw.schemaVersion !== 1) throw new Error("schemaVersion must be 1");
  const status = assertString(raw.status, "status");
  if (!["running", "completed", "failed", "partial"].includes(status)) {
    throw new Error("status must be one of running|completed|failed|partial");
  }
  const totalCases = Number(raw.totalCases);
  const passedCases = Number(raw.passedCases);
  const failedCases = Number(raw.failedCases);
  if (!Number.isFinite(totalCases) || totalCases < 0) throw new Error("totalCases must be a non-negative number");
  if (!Number.isFinite(passedCases) || passedCases < 0) throw new Error("passedCases must be a non-negative number");
  if (!Number.isFinite(failedCases) || failedCases < 0) throw new Error("failedCases must be a non-negative number");
  const metrics = parseOptionalEvalRunMetrics(raw.metrics);
  return {
    schemaVersion: 1,
    runId: assertString(raw.runId, "runId"),
    benchmarkId: assertString(raw.benchmarkId, "benchmarkId"),
    status,
    startedAt: assertString(raw.startedAt, "startedAt"),
    completedAt: typeof raw.completedAt === "string" && raw.completedAt.trim().length > 0 ? raw.completedAt.trim() : void 0,
    totalCases,
    passedCases,
    failedCases,
    metrics,
    notes: typeof raw.notes === "string" && raw.notes.trim().length > 0 ? raw.notes.trim() : void 0,
    gitRef: typeof raw.gitRef === "string" && raw.gitRef.trim().length > 0 ? raw.gitRef.trim() : void 0
  };
}
function validateEvalBaselineSnapshot(raw) {
  if (!isRecord(raw)) throw new Error("eval baseline snapshot must be an object");
  if (raw.schemaVersion !== 1) throw new Error("schemaVersion must be 1");
  if (!Array.isArray(raw.benchmarks)) throw new Error("benchmarks must be an array");
  const benchmarks = raw.benchmarks.map((item, index) => {
    if (!isRecord(item)) throw new Error(`benchmarks[${index}] must be an object`);
    const passRate = Number(item.passRate);
    if (!Number.isFinite(passRate) || passRate < 0 || passRate > 1) {
      throw new Error(`benchmarks[${index}].passRate must be a number between 0 and 1`);
    }
    const metrics = parseOptionalEvalRunMetrics(item.metrics);
    return {
      benchmarkId: assertString(item.benchmarkId, `benchmarks[${index}].benchmarkId`),
      runId: assertString(item.runId, `benchmarks[${index}].runId`),
      completedAt: typeof item.completedAt === "string" && item.completedAt.trim().length > 0 ? item.completedAt.trim() : void 0,
      gitRef: typeof item.gitRef === "string" && item.gitRef.trim().length > 0 ? item.gitRef.trim() : void 0,
      passRate,
      metrics
    };
  });
  const benchmarkCount = Number(raw.benchmarkCount);
  if (!Number.isFinite(benchmarkCount) || benchmarkCount < 0) {
    throw new Error("benchmarkCount must be a non-negative number");
  }
  if (benchmarkCount !== benchmarks.length) {
    throw new Error("benchmarkCount must match benchmarks.length");
  }
  return {
    schemaVersion: 1,
    snapshotId: assertString(raw.snapshotId, "snapshotId"),
    createdAt: assertString(raw.createdAt, "createdAt"),
    sourceRootDir: assertString(raw.sourceRootDir, "sourceRootDir"),
    benchmarkCount,
    benchmarks,
    notes: typeof raw.notes === "string" && raw.notes.trim().length > 0 ? raw.notes.trim() : void 0,
    gitRef: typeof raw.gitRef === "string" && raw.gitRef.trim().length > 0 ? raw.gitRef.trim() : void 0
  };
}
function parseOptionalEvalRunMetrics(raw) {
  if (!isRecord(raw)) return void 0;
  return {
    recallPrecisionAtK: typeof raw.recallPrecisionAtK === "number" ? raw.recallPrecisionAtK : void 0,
    actionOutcomeScore: typeof raw.actionOutcomeScore === "number" ? raw.actionOutcomeScore : void 0,
    objectiveStateCoverage: typeof raw.objectiveStateCoverage === "number" ? raw.objectiveStateCoverage : void 0,
    causalPathRecall: typeof raw.causalPathRecall === "number" ? raw.causalPathRecall : void 0,
    trustViolationRate: typeof raw.trustViolationRate === "number" ? raw.trustViolationRate : void 0,
    creationRecoveryScore: typeof raw.creationRecoveryScore === "number" ? raw.creationRecoveryScore : void 0
  };
}
function validateEvalShadowRecallRecord(raw) {
  if (!isRecord(raw)) throw new Error("eval shadow recall record must be an object");
  if (raw.schemaVersion !== 1) throw new Error("schemaVersion must be 1");
  const recallMode = assertString(raw.recallMode, "recallMode");
  if (!["no_recall", "minimal", "full", "graph_mode"].includes(recallMode)) {
    throw new Error("recallMode must be one of no_recall|minimal|full|graph_mode");
  }
  const source = assertString(raw.source, "source");
  if (!["none", "hot_qmd", "hot_embedding", "cold_fallback", "recent_scan"].includes(source)) {
    throw new Error("source must be one of none|hot_qmd|hot_embedding|cold_fallback|recent_scan");
  }
  const promptLength = Number(raw.promptLength);
  const retrievalQueryLength = Number(raw.retrievalQueryLength);
  const recallResultLimit = Number(raw.recallResultLimit);
  const recalledMemoryCount = Number(raw.recalledMemoryCount);
  const contextChars = Number(raw.contextChars);
  const durationMs = Number(raw.durationMs);
  for (const [field, value] of [
    ["promptLength", promptLength],
    ["retrievalQueryLength", retrievalQueryLength],
    ["recallResultLimit", recallResultLimit],
    ["recalledMemoryCount", recalledMemoryCount],
    ["contextChars", contextChars],
    ["durationMs", durationMs]
  ]) {
    if (!Number.isFinite(value) || value < 0) {
      throw new Error(`${field} must be a non-negative number`);
    }
  }
  const memoryIds = optionalStringArray(raw.memoryIds, "memoryIds") ?? [];
  if (typeof raw.injected !== "boolean") throw new Error("injected must be a boolean");
  let timings;
  if (raw.timings !== void 0) {
    if (!isRecord(raw.timings)) throw new Error("timings must be an object of strings");
    const out = {};
    for (const [key, value] of Object.entries(raw.timings)) {
      if (typeof value !== "string") throw new Error("timings must be an object of strings");
      out[key] = value;
    }
    timings = out;
  }
  const identityInjectionModeRaw = typeof raw.identityInjectionMode === "string" && raw.identityInjectionMode.trim().length > 0 ? raw.identityInjectionMode.trim() : void 0;
  if (identityInjectionModeRaw !== void 0 && !["recovery_only", "minimal", "full", "none"].includes(identityInjectionModeRaw)) {
    throw new Error("identityInjectionMode must be one of recovery_only|minimal|full|none");
  }
  return {
    schemaVersion: 1,
    traceId: assertString(raw.traceId, "traceId"),
    recordedAt: assertString(raw.recordedAt, "recordedAt"),
    sessionKey: assertString(raw.sessionKey, "sessionKey"),
    promptHash: assertString(raw.promptHash, "promptHash"),
    promptLength,
    retrievalQueryHash: assertString(raw.retrievalQueryHash, "retrievalQueryHash"),
    retrievalQueryLength,
    recallMode,
    recallResultLimit,
    source,
    recalledMemoryCount,
    injected: raw.injected,
    contextChars,
    memoryIds,
    policyVersion: typeof raw.policyVersion === "string" && raw.policyVersion.trim().length > 0 ? raw.policyVersion.trim() : void 0,
    identityInjectionMode: identityInjectionModeRaw,
    identityInjectedChars: typeof raw.identityInjectedChars === "number" && Number.isFinite(raw.identityInjectedChars) ? raw.identityInjectedChars : void 0,
    identityInjectionTruncated: typeof raw.identityInjectionTruncated === "boolean" ? raw.identityInjectionTruncated : void 0,
    durationMs,
    timings
  };
}
var LOWER_IS_BETTER_METRICS = /* @__PURE__ */ new Set(["trustViolationRate"]);
function computePassRate(run) {
  return run.totalCases > 0 ? run.passedCases / run.totalCases : 0;
}
function latestCompletedRunsByBenchmark(runs) {
  const sorted = [...runs].filter((run) => run.status === "completed").sort((a, b) => {
    const aTime = Date.parse(a.completedAt ?? a.startedAt);
    const bTime = Date.parse(b.completedAt ?? b.startedAt);
    return (Number.isNaN(bTime) ? 0 : bTime) - (Number.isNaN(aTime) ? 0 : aTime);
  });
  const out = /* @__PURE__ */ new Map();
  for (const run of sorted) {
    if (!out.has(run.benchmarkId)) {
      out.set(run.benchmarkId, run);
    }
  }
  return out;
}
function compareMetricDeltas(baseMetrics, candidateMetrics) {
  const deltas = {};
  const regressions = [];
  const improvements = [];
  if (!baseMetrics || !candidateMetrics) {
    return { deltas, regressions, improvements };
  }
  for (const metric of Object.keys(baseMetrics)) {
    const baseValue = baseMetrics[metric];
    const candidateValue = candidateMetrics[metric];
    if (typeof baseValue !== "number" || typeof candidateValue !== "number") continue;
    const delta = candidateValue - baseValue;
    deltas[metric] = delta;
    if (delta === 0) continue;
    const lowerIsBetter = LOWER_IS_BETTER_METRICS.has(metric);
    const improved = lowerIsBetter ? delta < 0 : delta > 0;
    const summary = `${metric} ${baseValue} -> ${candidateValue}`;
    if (improved) {
      improvements.push(summary);
    } else {
      regressions.push(summary);
    }
  }
  return { deltas, regressions, improvements };
}
function formatEvalBaselineDeltaMarkdown(report) {
  const lines = [
    "# Eval Baseline Delta Report",
    "",
    `- Passed: ${report.passed ? "yes" : "no"}`,
    `- Baseline snapshot: ${report.baselineSnapshotId}`,
    `- Baseline created: ${report.baselineCreatedAt}`,
    `- Baseline source root: ${report.baselineSourceRootDir}`,
    `- Candidate root: ${report.candidateRootDir}`,
    `- Benchmarks compared: ${report.comparedBenchmarks}`
  ];
  if (report.missingCandidateBenchmarks.length > 0) {
    lines.push(`- Missing candidate benchmarks: ${report.missingCandidateBenchmarks.join(", ")}`);
  }
  lines.push(
    `- Invalid candidate artifacts: benchmarks=${report.invalidArtifacts.candidate.benchmarks}, runs=${report.invalidArtifacts.candidate.runs}, shadows=${report.invalidArtifacts.candidate.shadows}, baselines=${report.invalidArtifacts.candidate.baselines}`,
    "",
    "## Regressions"
  );
  if (report.regressions.length === 0) {
    lines.push("- none");
  } else {
    for (const regression of report.regressions) lines.push(`- ${regression}`);
  }
  lines.push("", "## Improvements");
  if (report.improvements.length === 0) {
    lines.push("- none");
  } else {
    for (const improvement of report.improvements) lines.push(`- ${improvement}`);
  }
  lines.push("", "## Benchmark Deltas");
  if (report.deltas.length === 0) {
    lines.push("- none");
  } else {
    for (const delta of report.deltas) {
      lines.push(
        `- ${delta.benchmarkId}: passRate ${delta.basePassRate} -> ${delta.candidatePassRate} (delta ${delta.passRateDelta})`
      );
    }
  }
  return lines.join("\n");
}
async function collectEvalStoreSnapshot(options) {
  const rootDir = options.rootDir;
  const benchmarkDir = path.join(rootDir, "benchmarks");
  const runsDir = path.join(rootDir, "runs");
  const shadowDir = path.join(rootDir, "shadow");
  const baselineDir = path.join(rootDir, "baselines");
  const benchmarkFiles = await listNamedFiles(benchmarkDir, "manifest.json");
  const runFiles = await listJsonFiles(runsDir);
  const shadowFiles = await listJsonFiles(shadowDir);
  const baselineFiles = await listJsonFiles(baselineDir);
  const invalidBenchmarks = [];
  const invalidRuns = [];
  const invalidShadows = [];
  const invalidBaselines = [];
  const manifests = [];
  for (const filePath of benchmarkFiles) {
    try {
      manifests.push(
        validateEvalBenchmarkManifest(await readJsonFile(filePath), {
          memoryRedTeamBenchEnabled: options.memoryRedTeamBenchEnabled
        })
      );
    } catch (error) {
      invalidBenchmarks.push({
        path: filePath,
        error: error instanceof Error ? error.message : String(error)
      });
    }
  }
  const runs = [];
  for (const filePath of runFiles) {
    try {
      runs.push(validateEvalRunSummary(await readJsonFile(filePath)));
    } catch (error) {
      invalidRuns.push({
        path: filePath,
        error: error instanceof Error ? error.message : String(error)
      });
    }
  }
  const shadows = [];
  for (const filePath of shadowFiles) {
    try {
      shadows.push(validateEvalShadowRecallRecord(await readJsonFile(filePath)));
    } catch (error) {
      invalidShadows.push({
        path: filePath,
        error: error instanceof Error ? error.message : String(error)
      });
    }
  }
  const baselines = [];
  for (const filePath of baselineFiles) {
    try {
      baselines.push(validateEvalBaselineSnapshot(await readJsonFile(filePath)));
    } catch (error) {
      invalidBaselines.push({
        path: filePath,
        error: error instanceof Error ? error.message : String(error)
      });
    }
  }
  runs.sort((a, b) => {
    const aTime = Date.parse(a.completedAt ?? a.startedAt);
    const bTime = Date.parse(b.completedAt ?? b.startedAt);
    return (Number.isNaN(bTime) ? 0 : bTime) - (Number.isNaN(aTime) ? 0 : aTime);
  });
  shadows.sort((a, b) => b.recordedAt.localeCompare(a.recordedAt));
  baselines.sort((a, b) => b.createdAt.localeCompare(a.createdAt));
  const tags = /* @__PURE__ */ new Set();
  const attackClasses = /* @__PURE__ */ new Set();
  const sourceLinks = /* @__PURE__ */ new Set();
  const targetSurfaces = /* @__PURE__ */ new Set();
  let totalCases = 0;
  let redTeam = 0;
  for (const manifest of manifests) {
    totalCases += manifest.cases.length;
    if (manifest.benchmarkType === "memory-red-team") {
      redTeam += 1;
      if (manifest.attackClass) attackClasses.add(manifest.attackClass);
      if (manifest.targetSurface) targetSurfaces.add(manifest.targetSurface);
    }
    for (const tag of manifest.tags ?? []) tags.add(tag);
    for (const link of manifest.sourceLinks ?? []) sourceLinks.add(link);
  }
  return {
    status: {
      enabled: options.enabled,
      shadowModeEnabled: options.shadowModeEnabled,
      rootDir,
      benchmarkDir,
      runsDir,
      benchmarks: {
        total: benchmarkFiles.length,
        valid: manifests.length,
        invalid: invalidBenchmarks.length,
        redTeam,
        totalCases,
        attackClasses: [...attackClasses].sort(),
        tags: [...tags].sort(),
        targetSurfaces: [...targetSurfaces].sort(),
        sourceLinks: [...sourceLinks].sort()
      },
      runs: {
        total: runFiles.length,
        invalid: invalidRuns.length,
        completed: runs.filter((run) => run.status === "completed").length,
        failed: runs.filter((run) => run.status === "failed").length,
        partial: runs.filter((run) => run.status === "partial").length,
        running: runs.filter((run) => run.status === "running").length,
        latestRunId: runs[0]?.runId,
        latestBenchmarkId: runs[0]?.benchmarkId,
        latestCompletedAt: runs[0]?.completedAt
      },
      shadows: {
        total: shadowFiles.length,
        invalid: invalidShadows.length,
        latestTraceId: shadows[0]?.traceId,
        latestRecordedAt: shadows[0]?.recordedAt,
        latestSessionKey: shadows[0]?.sessionKey
      },
      baselines: {
        enabled: options.baselineSnapshotsEnabled === true,
        total: baselineFiles.length,
        invalid: invalidBaselines.length,
        latestSnapshotId: baselines[0]?.snapshotId,
        latestCreatedAt: baselines[0]?.createdAt,
        latestBenchmarkCount: baselines[0]?.benchmarkCount
      },
      latestRun: runs[0],
      latestShadow: shadows[0],
      latestBaseline: baselines[0],
      invalidBenchmarks,
      invalidRuns,
      invalidShadows,
      invalidBaselines
    },
    manifests,
    runs,
    shadows,
    baselines
  };
}
async function resolveBenchmarkManifestPath(sourcePath) {
  const info = await stat(sourcePath);
  if (info.isDirectory()) {
    return {
      sourceKind: "directory",
      manifestPath: path.join(sourcePath, "manifest.json")
    };
  }
  if (info.isFile()) {
    return {
      sourceKind: "file",
      manifestPath: sourcePath
    };
  }
  throw new Error("benchmark pack source must be a file or directory");
}
async function validateEvalBenchmarkPack(sourcePath, options) {
  const trimmedSourcePath = sourcePath.trim();
  if (trimmedSourcePath.length === 0) {
    throw new Error("benchmark pack path must be a non-empty string");
  }
  const { manifestPath } = await resolveBenchmarkManifestPath(trimmedSourcePath);
  const manifest = validateEvalBenchmarkManifest(await readJsonFile(manifestPath), {
    memoryRedTeamBenchEnabled: options?.memoryRedTeamBenchEnabled
  });
  return {
    sourcePath: trimmedSourcePath,
    manifestPath,
    benchmarkId: assertSafeBenchmarkId(manifest.benchmarkId),
    benchmarkType: manifest.benchmarkType ?? "standard",
    title: manifest.title,
    attackClass: manifest.attackClass,
    targetSurface: manifest.targetSurface,
    totalCases: manifest.cases.length,
    tags: [...manifest.tags ?? []],
    sourceLinks: [...manifest.sourceLinks ?? []]
  };
}
async function importEvalBenchmarkPack(options) {
  const summary = await validateEvalBenchmarkPack(options.sourcePath, {
    memoryRedTeamBenchEnabled: options.memoryRedTeamBenchEnabled
  });
  const rootDir = resolveEvalStoreDir(options.memoryDir, options.evalStoreDir);
  const benchmarkDir = path.join(rootDir, "benchmarks");
  const targetDir = path.join(benchmarkDir, summary.benchmarkId);
  const { sourceKind, manifestPath } = await resolveBenchmarkManifestPath(summary.sourcePath);
  let overwritten = false;
  try {
    await stat(targetDir);
    if (options.force !== true) {
      throw new Error(`benchmark pack already exists at ${targetDir}; rerun with force to replace it`);
    }
    overwritten = true;
    await rm(targetDir, { recursive: true, force: true });
  } catch (error) {
    if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
      throw error;
    }
  }
  await mkdir(benchmarkDir, { recursive: true });
  if (sourceKind === "directory") {
    await cp(summary.sourcePath, targetDir, { recursive: true });
  } else {
    await mkdir(targetDir, { recursive: true });
    await cp(manifestPath, path.join(targetDir, "manifest.json"));
  }
  return {
    ...summary,
    targetDir,
    overwritten
  };
}
async function recordEvalShadowRecall(options) {
  const rootDir = resolveEvalStoreDir(options.memoryDir, options.evalStoreDir);
  const validated = validateEvalShadowRecallRecord(options.record);
  const day = validated.recordedAt.slice(0, 10);
  const shadowDir = path.join(rootDir, "shadow", day);
  const targetPath = path.join(shadowDir, `${validated.traceId}.json`);
  await mkdir(shadowDir, { recursive: true });
  await writeFile(targetPath, JSON.stringify(validated, null, 2), "utf-8");
  return targetPath;
}
async function getEvalHarnessStatus(options) {
  return (await collectEvalStoreSnapshot({
    rootDir: resolveEvalStoreDir(options.memoryDir, options.evalStoreDir),
    enabled: options.enabled,
    shadowModeEnabled: options.shadowModeEnabled,
    baselineSnapshotsEnabled: options.baselineSnapshotsEnabled,
    memoryRedTeamBenchEnabled: options.memoryRedTeamBenchEnabled
  })).status;
}
async function createEvalBaselineSnapshot(options) {
  if (options.baselineSnapshotsEnabled !== true) {
    throw new Error("benchmark baseline snapshots are disabled");
  }
  const snapshotId = assertSafePathSegment(assertString(options.snapshotId, "snapshotId"), "snapshotId");
  const rootDir = resolveEvalStoreDir(options.memoryDir, options.evalStoreDir);
  const store = await collectEvalStoreSnapshot({
    rootDir,
    enabled: true,
    shadowModeEnabled: true,
    baselineSnapshotsEnabled: true,
    memoryRedTeamBenchEnabled: true
  });
  const latestRuns = latestCompletedRunsByBenchmark(store.runs);
  const benchmarks = [...latestRuns.values()].sort((a, b) => a.benchmarkId.localeCompare(b.benchmarkId)).map((run) => ({
    benchmarkId: run.benchmarkId,
    runId: run.runId,
    completedAt: run.completedAt,
    gitRef: run.gitRef,
    passRate: computePassRate(run),
    metrics: run.metrics
  }));
  const snapshot = validateEvalBaselineSnapshot({
    schemaVersion: 1,
    snapshotId,
    createdAt: options.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
    sourceRootDir: rootDir,
    benchmarkCount: benchmarks.length,
    benchmarks,
    notes: options.notes,
    gitRef: options.gitRef
  });
  const targetPath = path.join(rootDir, "baselines", `${snapshot.snapshotId}.json`);
  await mkdir(path.dirname(targetPath), { recursive: true });
  await writeFile(targetPath, JSON.stringify(snapshot, null, 2), "utf-8");
  return { targetPath, snapshot };
}
async function runEvalBaselineDeltaReport(options) {
  if (options.benchmarkDeltaReporterEnabled !== true) {
    throw new Error("benchmark delta reporter is disabled");
  }
  const snapshotId = assertSafePathSegment(assertString(options.snapshotId, "snapshotId"), "snapshotId");
  const candidateRootDir = resolveEvalStoreDir(options.memoryDir, options.evalStoreDir);
  const candidateSnapshot = await collectEvalStoreSnapshot({
    rootDir: candidateRootDir,
    enabled: true,
    shadowModeEnabled: true,
    baselineSnapshotsEnabled: true,
    memoryRedTeamBenchEnabled: true
  });
  const baselineSnapshot = candidateSnapshot.baselines.find((snapshot) => snapshot.snapshotId === snapshotId);
  if (!baselineSnapshot) {
    throw new Error(`benchmark baseline snapshot not found: ${snapshotId}`);
  }
  return buildEvalBaselineDeltaReport({
    baselineSnapshot,
    candidateSnapshot
  });
}
async function runEvalStoredBaselineCiGate(options) {
  const snapshotId = assertSafePathSegment(assertString(options.snapshotId, "snapshotId"), "snapshotId");
  const baseRootDir = resolveEvalStoreDir(options.baseMemoryDir ?? options.baseEvalStoreDir, options.baseEvalStoreDir);
  const candidateRootDir = resolveEvalStoreDir(
    options.candidateMemoryDir ?? options.candidateEvalStoreDir,
    options.candidateEvalStoreDir
  );
  const [baseSnapshot, candidateSnapshot] = await Promise.all([
    collectEvalStoreSnapshot({
      rootDir: baseRootDir,
      enabled: true,
      shadowModeEnabled: true,
      baselineSnapshotsEnabled: true,
      memoryRedTeamBenchEnabled: true
    }),
    collectEvalStoreSnapshot({
      rootDir: candidateRootDir,
      enabled: true,
      shadowModeEnabled: true,
      baselineSnapshotsEnabled: true,
      memoryRedTeamBenchEnabled: true
    })
  ]);
  const baselineSnapshot = baseSnapshot.baselines.find((snapshot) => snapshot.snapshotId === snapshotId) ?? candidateSnapshot.baselines.find((snapshot) => snapshot.snapshotId === snapshotId);
  if (!baselineSnapshot) {
    throw new Error(`benchmark baseline snapshot not found: ${snapshotId}`);
  }
  return {
    baseRootDir,
    baselineResolvedFrom: baseSnapshot.baselines.some((snapshot) => snapshot.snapshotId === snapshotId) ? "base" : "candidate",
    ...buildEvalBaselineDeltaReport({
      baselineSnapshot,
      candidateSnapshot
    })
  };
}
function buildEvalBaselineDeltaReport(options) {
  const { baselineSnapshot, candidateSnapshot } = options;
  const regressions = [];
  const improvements = [];
  if (candidateSnapshot.status.invalidBenchmarks.length > 0) {
    regressions.push(`candidate store has ${candidateSnapshot.status.invalidBenchmarks.length} invalid benchmark manifest(s)`);
  }
  if (candidateSnapshot.status.invalidRuns.length > 0) {
    regressions.push(`candidate store has ${candidateSnapshot.status.invalidRuns.length} invalid run summary file(s)`);
  }
  if (candidateSnapshot.status.invalidShadows.length > 0) {
    regressions.push(`candidate store has ${candidateSnapshot.status.invalidShadows.length} invalid shadow record(s)`);
  }
  if (candidateSnapshot.status.invalidBaselines.length > 0) {
    regressions.push(`candidate store has ${candidateSnapshot.status.invalidBaselines.length} invalid baseline snapshot file(s)`);
  }
  const candidateRuns = latestCompletedRunsByBenchmark(candidateSnapshot.runs);
  const baselineBenchmarks = new Map(
    baselineSnapshot.benchmarks.map((benchmark) => [benchmark.benchmarkId, benchmark])
  );
  const missingCandidateBenchmarks = [...baselineBenchmarks.keys()].filter((benchmarkId) => !candidateRuns.has(benchmarkId)).sort();
  for (const benchmarkId of missingCandidateBenchmarks) {
    regressions.push(`candidate is missing latest completed benchmark run for ${benchmarkId}`);
  }
  const deltas = [];
  for (const benchmarkId of [...baselineBenchmarks.keys()].sort()) {
    const baseBenchmark = baselineBenchmarks.get(benchmarkId);
    const candidateRun = candidateRuns.get(benchmarkId);
    if (!baseBenchmark || !candidateRun) continue;
    const passRateDelta = computePassRate(candidateRun) - baseBenchmark.passRate;
    const delta = {
      benchmarkId,
      baseRunId: baseBenchmark.runId,
      candidateRunId: candidateRun.runId,
      basePassRate: baseBenchmark.passRate,
      candidatePassRate: computePassRate(candidateRun),
      passRateDelta,
      metricDeltas: {},
      regressions: [],
      improvements: []
    };
    if (passRateDelta < 0) {
      delta.regressions.push(`passRate ${baseBenchmark.passRate} -> ${delta.candidatePassRate}`);
      regressions.push(`${benchmarkId} pass rate regressed (${baseBenchmark.passRate} -> ${delta.candidatePassRate})`);
    } else if (passRateDelta > 0) {
      delta.improvements.push(`passRate ${baseBenchmark.passRate} -> ${delta.candidatePassRate}`);
      improvements.push(`${benchmarkId} pass rate improved (${baseBenchmark.passRate} -> ${delta.candidatePassRate})`);
    }
    const metricDelta = compareMetricDeltas(baseBenchmark.metrics, candidateRun.metrics);
    delta.metricDeltas = metricDelta.deltas;
    for (const regression of metricDelta.regressions) {
      delta.regressions.push(regression);
      regressions.push(`${benchmarkId} ${regression}`);
    }
    for (const improvement of metricDelta.improvements) {
      delta.improvements.push(improvement);
      improvements.push(`${benchmarkId} ${improvement}`);
    }
    deltas.push(delta);
  }
  const report = {
    passed: regressions.length === 0,
    baselineSnapshotId: baselineSnapshot.snapshotId,
    baselineCreatedAt: baselineSnapshot.createdAt,
    baselineSourceRootDir: baselineSnapshot.sourceRootDir,
    candidateRootDir: candidateSnapshot.status.rootDir,
    comparedBenchmarks: deltas.length,
    missingCandidateBenchmarks,
    invalidArtifacts: {
      candidate: {
        benchmarks: candidateSnapshot.status.invalidBenchmarks.length,
        runs: candidateSnapshot.status.invalidRuns.length,
        shadows: candidateSnapshot.status.invalidShadows.length,
        baselines: candidateSnapshot.status.invalidBaselines.length
      }
    },
    regressions,
    improvements,
    deltas,
    markdownReport: ""
  };
  report.markdownReport = formatEvalBaselineDeltaMarkdown(report);
  return report;
}
function resolveRequiredEvalStoreRoot(options, label) {
  if (typeof options.evalStoreDir === "string" && options.evalStoreDir.trim().length > 0) {
    return options.evalStoreDir.trim();
  }
  if (typeof options.memoryDir === "string" && options.memoryDir.trim().length > 0) {
    return resolveEvalStoreDir(options.memoryDir.trim());
  }
  throw new Error(`${label} requires memoryDir or evalStoreDir`);
}
async function runEvalBenchmarkCiGate(options) {
  const baseRootDir = resolveRequiredEvalStoreRoot(
    { memoryDir: options.baseMemoryDir, evalStoreDir: options.baseEvalStoreDir },
    "base"
  );
  const candidateRootDir = resolveRequiredEvalStoreRoot(
    { memoryDir: options.candidateMemoryDir, evalStoreDir: options.candidateEvalStoreDir },
    "candidate"
  );
  const baseSnapshot = await collectEvalStoreSnapshot({
    rootDir: baseRootDir,
    enabled: true,
    shadowModeEnabled: true,
    memoryRedTeamBenchEnabled: true
  });
  const candidateSnapshot = await collectEvalStoreSnapshot({
    rootDir: candidateRootDir,
    enabled: true,
    shadowModeEnabled: true,
    memoryRedTeamBenchEnabled: true
  });
  const regressions = [];
  const improvements = [];
  if (baseSnapshot.status.invalidBenchmarks.length > 0) {
    regressions.push(`base store has ${baseSnapshot.status.invalidBenchmarks.length} invalid benchmark manifest(s)`);
  }
  if (baseSnapshot.status.invalidRuns.length > 0) {
    regressions.push(`base store has ${baseSnapshot.status.invalidRuns.length} invalid run summary file(s)`);
  }
  if (baseSnapshot.status.invalidShadows.length > 0) {
    regressions.push(`base store has ${baseSnapshot.status.invalidShadows.length} invalid shadow record(s)`);
  }
  if (candidateSnapshot.status.invalidBenchmarks.length > 0) {
    regressions.push(`candidate store has ${candidateSnapshot.status.invalidBenchmarks.length} invalid benchmark manifest(s)`);
  }
  if (candidateSnapshot.status.invalidRuns.length > 0) {
    regressions.push(`candidate store has ${candidateSnapshot.status.invalidRuns.length} invalid run summary file(s)`);
  }
  if (candidateSnapshot.status.invalidShadows.length > 0) {
    regressions.push(`candidate store has ${candidateSnapshot.status.invalidShadows.length} invalid shadow record(s)`);
  }
  const baseRuns = latestCompletedRunsByBenchmark(baseSnapshot.runs);
  const candidateRuns = latestCompletedRunsByBenchmark(candidateSnapshot.runs);
  const missingCandidateBenchmarks = [...baseRuns.keys()].filter((benchmarkId) => !candidateRuns.has(benchmarkId)).sort();
  for (const benchmarkId of missingCandidateBenchmarks) {
    regressions.push(`candidate is missing latest completed benchmark run for ${benchmarkId}`);
  }
  const deltas = [];
  for (const benchmarkId of [...baseRuns.keys()].sort()) {
    const baseRun = baseRuns.get(benchmarkId);
    const candidateRun = candidateRuns.get(benchmarkId);
    if (!baseRun || !candidateRun) continue;
    const basePassRate = computePassRate(baseRun);
    const candidatePassRate = computePassRate(candidateRun);
    const passRateDelta = candidatePassRate - basePassRate;
    const delta = {
      benchmarkId,
      baseRunId: baseRun.runId,
      candidateRunId: candidateRun.runId,
      basePassRate,
      candidatePassRate,
      passRateDelta,
      metricDeltas: {},
      regressions: [],
      improvements: []
    };
    if (passRateDelta < 0) {
      delta.regressions.push(`passRate ${basePassRate} -> ${candidatePassRate}`);
      regressions.push(`${benchmarkId} pass rate regressed (${basePassRate} -> ${candidatePassRate})`);
    } else if (passRateDelta > 0) {
      delta.improvements.push(`passRate ${basePassRate} -> ${candidatePassRate}`);
      improvements.push(`${benchmarkId} pass rate improved (${basePassRate} -> ${candidatePassRate})`);
    }
    const metricDelta = compareMetricDeltas(baseRun.metrics, candidateRun.metrics);
    delta.metricDeltas = metricDelta.deltas;
    for (const regression of metricDelta.regressions) {
      delta.regressions.push(regression);
      regressions.push(`${benchmarkId} ${regression}`);
    }
    for (const improvement of metricDelta.improvements) {
      delta.improvements.push(improvement);
      improvements.push(`${benchmarkId} ${improvement}`);
    }
    deltas.push(delta);
  }
  return {
    passed: regressions.length === 0,
    baseRootDir: baseSnapshot.status.rootDir,
    candidateRootDir: candidateSnapshot.status.rootDir,
    comparedBenchmarks: deltas.length,
    missingCandidateBenchmarks,
    invalidArtifacts: {
      base: {
        benchmarks: baseSnapshot.status.invalidBenchmarks.length,
        runs: baseSnapshot.status.invalidRuns.length,
        shadows: baseSnapshot.status.invalidShadows.length
      },
      candidate: {
        benchmarks: candidateSnapshot.status.invalidBenchmarks.length,
        runs: candidateSnapshot.status.invalidRuns.length,
        shadows: candidateSnapshot.status.invalidShadows.length
      }
    },
    regressions,
    improvements,
    deltas
  };
}

export {
  resolveEvalStoreDir,
  validateEvalBenchmarkManifest,
  validateEvalRunSummary,
  validateEvalBaselineSnapshot,
  validateEvalShadowRecallRecord,
  validateEvalBenchmarkPack,
  importEvalBenchmarkPack,
  recordEvalShadowRecall,
  getEvalHarnessStatus,
  createEvalBaselineSnapshot,
  runEvalBaselineDeltaReport,
  runEvalStoredBaselineCiGate,
  runEvalBenchmarkCiGate
};
//# sourceMappingURL=chunk-K6WK37A6.js.map