import {
  buildLoopProvenanceRecord,
  composeGate,
  countSentenceEdits,
  defaultProductionGate,
  defaultRenderDiff,
  emitLoopProvenance,
  evolutionaryDriver,
  extractH2Sections,
  gepaDriver,
  heldOutGate,
  isProposedCandidate,
  labelTrustRank,
  loopProvenanceSpans,
  openAutoPr,
  provenanceRecordPath,
  provenanceSpansPath,
  runEval,
  runImprovementLoop,
  runOptimization,
  surfaceContentHash,
  surfaceHash
} from "../chunk-SUGME4OT.js";
import {
  fsCampaignStorage,
  inMemoryCampaignStorage,
  runCampaign
} from "../chunk-OLULBECP.js";
import {
  agentProfileHash
} from "../chunk-PQV2TKC3.js";
import {
  assertRealBackend,
  summarizeBackendIntegrity
} from "../chunk-GMXHLSLL.js";
import "../chunk-YV7J7X5N.js";
import {
  validateRunRecord
} from "../chunk-F3SRAAZO.js";
import "../chunk-ITBRCT73.js";
import "../chunk-GGE4NNQT.js";
import "../chunk-VSMTAMNK.js";
import "../chunk-IHDHUN2X.js";
import "../chunk-PC4UYEBM.js";
import {
  AgentEvalError
} from "../chunk-3BFEG2F6.js";
import "../chunk-PZ5AY32C.js";

// src/campaign/labeled-store/fs-adapter.ts
import { createHash } from "crypto";
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
import { join } from "path";
var LabeledScenarioStoreError = class extends Error {
  constructor(code, message) {
    super(message);
    this.code = code;
    this.name = "LabeledScenarioStoreError";
  }
  code;
};
var FsLabeledScenarioStore = class {
  constructor(options) {
    this.options = options;
    if (!existsSync(options.root)) mkdirSync(options.root, { recursive: true });
    this.now = options.now ?? Date.now;
  }
  options;
  now;
  rateLimits = /* @__PURE__ */ new Map();
  async observe(write) {
    this.assertProvenance(write);
    this.assertRateLimit(write);
    const record = this.toRecord(write);
    const path = this.pathForSource(write.source);
    const line = `${JSON.stringify(record)}
`;
    appendLine(path, line);
  }
  async sample(args) {
    if (!args.split) {
      throw new LabeledScenarioStoreError(
        "split_required",
        "sample() requires an explicit `split` (train | test) \u2014 substrate refuses ambiguous reads"
      );
    }
    if (!args.capturedBefore) {
      throw new LabeledScenarioStoreError(
        "capturedBefore_required",
        "sample() requires an explicit `capturedBefore` timestamp for temporal-split discipline"
      );
    }
    const all = [];
    for (const source of ALL_SOURCES) {
      if (args.split === "train" && source === "production-trace") {
        const explicit = sourceFilterContains(args.filter?.source, "production-trace");
        if (!explicit) continue;
      }
      const path = this.pathForSource(source);
      if (!existsSync(path)) continue;
      const lines = readFileSync(path, "utf8").split("\n").filter(Boolean);
      for (const line of lines) {
        let record;
        try {
          record = JSON.parse(line);
        } catch {
          continue;
        }
        if (!matchesFilter(record, args, source)) continue;
        all.push(record);
      }
    }
    all.sort((a, b) => {
      if (a.capturedAt !== b.capturedAt) return a.capturedAt.localeCompare(b.capturedAt);
      return a.recordHash.localeCompare(b.recordHash);
    });
    return all.slice(0, args.count);
  }
  async size() {
    const bySource = {};
    const byTrust = {
      unverified: 0,
      "verified-signal": 0,
      "human-rated": 0
    };
    let total = 0;
    for (const source of ALL_SOURCES) {
      const path = this.pathForSource(source);
      if (!existsSync(path)) {
        bySource[source] = 0;
        continue;
      }
      const lines = readFileSync(path, "utf8").split("\n").filter(Boolean);
      bySource[source] = lines.length;
      total += lines.length;
      for (const line of lines) {
        let trust = "unverified";
        try {
          trust = JSON.parse(line).labelTrust ?? "unverified";
        } catch {
        }
        byTrust[trust] += 1;
      }
    }
    return { train: total, test: total, bySource, byTrust };
  }
  assertProvenance(write) {
    if (!write.source) {
      throw new LabeledScenarioStoreError(
        "missing_source",
        "LabeledScenarioWrite requires `source`"
      );
    }
    if (!write.sourceVersionHash || write.sourceVersionHash.length === 0) {
      throw new LabeledScenarioStoreError(
        "missing_source_version",
        "LabeledScenarioWrite requires `sourceVersionHash` (git sha or substrate version)"
      );
    }
    if (!write.capturedAt) {
      throw new LabeledScenarioStoreError(
        "missing_captured_at",
        "LabeledScenarioWrite requires `capturedAt` ISO timestamp"
      );
    }
    if (!write.redactionStatus) {
      throw new LabeledScenarioStoreError(
        "missing_redaction_status",
        "LabeledScenarioWrite requires explicit `redactionStatus` \u2014 raw / redacted-pii / redacted-secrets / fully-redacted"
      );
    }
    if (!ALL_SOURCES.includes(write.source)) {
      throw new LabeledScenarioStoreError(
        "unknown_source",
        `LabeledScenarioWrite.source must be one of: ${ALL_SOURCES.join(", ")}`
      );
    }
  }
  assertRateLimit(write) {
    const cap = this.options.maxWritesPerMinutePerBucket;
    if (!cap || !write.rateLimitBucket) return;
    const now = this.now();
    const windowMs = 6e4;
    let state = this.rateLimits.get(write.rateLimitBucket);
    if (!state || now - state.windowStartMs >= windowMs) {
      state = { bucket: write.rateLimitBucket, windowStartMs: now, count: 0 };
      this.rateLimits.set(write.rateLimitBucket, state);
    }
    if (state.count >= cap) {
      throw new LabeledScenarioStoreError(
        "rate_limit_exceeded",
        `LabeledScenarioStore: bucket ${write.rateLimitBucket} exceeded ${cap} writes/min`
      );
    }
    state.count += 1;
  }
  toRecord(write) {
    const recordHash = sha256(
      JSON.stringify({
        id: write.scenario.id,
        src: write.source,
        at: write.capturedAt,
        ver: write.sourceVersionHash
      })
    );
    return {
      ...write,
      recordHash,
      split: "train"
    };
  }
  pathForSource(source) {
    return join(this.options.root, `${source}.jsonl`);
  }
};
var ALL_SOURCES = [
  "production-trace",
  "eval-run",
  "manual",
  "red-team",
  "synthetic"
];
function sourceFilterContains(filter, needle) {
  if (!filter) return false;
  if (Array.isArray(filter)) return filter.includes(needle);
  return filter === needle;
}
function matchesFilter(record, args, source) {
  if (args.split === "train" && record.capturedAt >= args.capturedBefore) return false;
  if (args.split === "test" && record.capturedAt < args.capturedBefore) return false;
  const f = args.filter;
  if (!f) return true;
  if (f.kind && record.scenario.kind !== f.kind) return false;
  if (f.source) {
    const sources = Array.isArray(f.source) ? f.source : [f.source];
    if (!sources.includes(source)) return false;
  }
  if (f.minComposite !== void 0 || f.maxComposite !== void 0) {
    const composites = Object.values(record.judgeScores).map((s) => s.composite);
    const max = composites.length === 0 ? 0 : Math.max(...composites);
    if (f.minComposite !== void 0 && max < f.minComposite) return false;
    if (f.maxComposite !== void 0 && max > f.maxComposite) return false;
  }
  if (f.minTrust !== void 0 && labelTrustRank(record.labelTrust) < labelTrustRank(f.minTrust)) {
    return false;
  }
  return true;
}
function sha256(input) {
  return createHash("sha256").update(input).digest("hex").slice(0, 16);
}
function appendLine(path, line) {
  if (existsSync(path)) {
    const existing = readFileSync(path, "utf8");
    writeFileSync(path, existing + line);
  } else {
    writeFileSync(path, line);
  }
}

// src/campaign/presets/run-profile-matrix.ts
import { createHash as createHash2 } from "crypto";
import { join as join2 } from "path";
var ProfileMatrixError = class extends AgentEvalError {
  constructor(message) {
    super("profile_matrix", message);
  }
};
function sanitize(id) {
  return id.replace(/[^a-zA-Z0-9_-]/g, "_");
}
function sha(input) {
  return createHash2("sha256").update(JSON.stringify(input)).digest("hex");
}
function mean(xs) {
  return xs.length === 0 ? 0 : xs.reduce((a, b) => a + b, 0) / xs.length;
}
function cellComposite(cell) {
  const composites = Object.values(cell.judgeScores).map((s) => s.composite);
  return composites.length === 0 ? 0 : mean(composites);
}
function buildRunRecord(args) {
  const { cell, profile, profileHash, configHash, experimentId, splitTag, commitSha, matrixId } = args;
  const composite = cellComposite(cell);
  const raw = { composite };
  const perJudge = {};
  const dimAccum = {};
  const notes = [];
  for (const [judgeName, js] of Object.entries(cell.judgeScores)) {
    perJudge[judgeName] = { ...js.dimensions };
    for (const [dim, value] of Object.entries(js.dimensions)) {
      raw[`${judgeName}.${dim}`] = value;
      (dimAccum[dim] ??= []).push(value);
    }
    if (js.notes) notes.push(`${judgeName}: ${js.notes}`);
  }
  const perDimMean = {};
  for (const [dim, values] of Object.entries(dimAccum)) perDimMean[dim] = mean(values);
  const outcome = splitTag === "holdout" ? { holdoutScore: composite, raw } : { searchScore: composite, raw };
  if (Object.keys(perJudge).length > 0) {
    outcome.judgeScores = {
      perJudge,
      perDimMean,
      composite,
      ...notes.length > 0 ? { notes: notes.join(" | ") } : {}
    };
  }
  return {
    runId: `${matrixId}:${profile.id}:${cell.cellId}`,
    experimentId,
    candidateId: profile.id,
    seed: cell.seed,
    model: profile.model,
    promptHash: profileHash,
    configHash,
    commitSha,
    wallMs: cell.durationMs,
    costUsd: cell.costUsd,
    tokenUsage: cell.tokenUsage,
    outcome,
    splitTag,
    scenarioId: cell.scenarioId,
    ...cell.error ? { failureMode: cell.error } : {}
  };
}
async function runProfileMatrix(opts) {
  if (opts.profiles.length === 0) throw new ProfileMatrixError("profiles must not be empty");
  if (opts.scenarios.length === 0) throw new ProfileMatrixError("scenarios must not be empty");
  const splitTag = opts.splitTag ?? "search";
  const seed = opts.seed ?? 42;
  const validate = opts.validate ?? true;
  const integrityMode = opts.integrity ?? "assert";
  const profileIds = opts.profiles.map((p) => p.id);
  const experimentId = opts.experimentId ?? `pm_${sha({ profileIds, scenarios: opts.scenarios.map((s) => s.id) }).slice(0, 16)}`;
  const matrixId = `mtx_${sha({ experimentId, profileIds, seed, splitTag }).slice(0, 16)}`;
  for (const profile of opts.profiles) {
    const profileHash = agentProfileHash(profile);
    try {
      validateRunRecord({
        runId: `${matrixId}:${profile.id}:probe`,
        experimentId,
        candidateId: profile.id,
        seed,
        model: profile.model,
        promptHash: profileHash,
        configHash: profileHash,
        commitSha: opts.commitSha,
        wallMs: 0,
        costUsd: 0,
        tokenUsage: { input: 0, output: 0 },
        outcome: splitTag === "holdout" ? { holdoutScore: 0, raw: {} } : { searchScore: 0, raw: {} },
        splitTag
      });
    } catch (err) {
      throw new ProfileMatrixError(
        `profile '${profile.id}' is not recordable: ${err instanceof Error ? err.message : String(err)}`
      );
    }
  }
  const records = [];
  const campaigns = {};
  const byProfile = {};
  for (const profile of opts.profiles) {
    const profileHash = agentProfileHash(profile);
    const configHash = sha({
      profile: profileHash,
      judges: (opts.judges ?? []).map((j) => j.name),
      seed,
      splitTag
    });
    const dispatch = (scenario, ctx) => opts.dispatch(profile, scenario, ctx);
    Object.defineProperty(dispatch, "name", { value: `profile_${sanitize(profile.id)}` });
    const campaign = await runCampaign({
      scenarios: opts.scenarios,
      dispatch,
      judges: opts.judges,
      seed,
      reps: opts.reps,
      maxConcurrency: opts.maxConcurrency,
      costCeiling: opts.costCeiling,
      labeledStore: opts.labeledStore,
      captureSource: opts.captureSource,
      storage: opts.storage,
      now: opts.now,
      runDir: join2(opts.runDir, sanitize(profile.id))
    });
    campaigns[profile.id] = campaign;
    const profileRecords = [];
    for (const cell of campaign.cells) {
      const record = buildRunRecord({
        cell,
        profile,
        profileHash,
        configHash,
        experimentId,
        splitTag,
        commitSha: opts.commitSha,
        matrixId
      });
      if (validate) validateRunRecord(record);
      profileRecords.push(record);
      records.push(record);
    }
    byProfile[profile.id] = {
      profileId: profile.id,
      profileHash,
      model: profile.model,
      records: profileRecords.length,
      meanComposite: mean(profileRecords.map(compositeOf)),
      totalCostUsd: profileRecords.reduce((a, r) => a + r.costUsd, 0),
      integrity: summarizeBackendIntegrity(profileRecords)
    };
  }
  const integrity = summarizeBackendIntegrity(records);
  if (integrityMode === "assert") {
    assertRealBackend(records, { allowMixed: opts.allowMixed ?? true });
  } else if (integrityMode === "warn" && integrity.verdict !== "real") {
    console.warn(
      `[runProfileMatrix] backend integrity: ${integrity.verdict} \u2014 ${integrity.diagnosis}`
    );
  }
  const byScenario = rollup(records, (r) => r.scenarioId);
  const byPersona = opts.personaOf ? rollupByPersona(records, opts.scenarios, opts.personaOf) : void 0;
  return { matrixId, experimentId, records, byProfile, byScenario, byPersona, integrity, campaigns };
}
function compositeOf(r) {
  return r.outcome.holdoutScore ?? r.outcome.searchScore ?? 0;
}
function rollup(records, keyOf) {
  const groups = /* @__PURE__ */ new Map();
  for (const r of records) {
    const key = keyOf(r);
    if (key === void 0) continue;
    const arr = groups.get(key) ?? [];
    arr.push(compositeOf(r));
    groups.set(key, arr);
  }
  const out = {};
  for (const [key, xs] of groups) out[key] = { meanComposite: mean(xs), n: xs.length };
  return out;
}
function rollupByPersona(records, scenarios, personaOf) {
  const personaByScenarioId = /* @__PURE__ */ new Map();
  for (const s of scenarios) personaByScenarioId.set(s.id, personaOf(s));
  return rollup(records, (r) => r.scenarioId ? personaByScenarioId.get(r.scenarioId) : void 0);
}

// src/campaign/worktree/index.ts
import { execFileSync } from "child_process";
import { existsSync as existsSync2 } from "fs";
import { basename, isAbsolute, join as join3 } from "path";
var WorktreeAdapterError = class extends Error {
  constructor(message, cause) {
    super(message);
    this.cause = cause;
    this.name = "WorktreeAdapterError";
  }
  cause;
};
function defaultGit(args, cwd) {
  try {
    return execFileSync("git", args, { cwd, encoding: "utf8" }).trim();
  } catch (err) {
    const stderr = err && typeof err === "object" && "stderr" in err ? String(err.stderr) : "";
    throw new WorktreeAdapterError(`git ${args.join(" ")} failed: ${stderr || String(err)}`, err);
  }
}
function slug(label) {
  return label.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 48) || "candidate";
}
function gitWorktreeAdapter(opts) {
  const git = opts.git ?? defaultGit;
  const worktreeDir = opts.worktreeDir ?? join3(opts.repoRoot, ".worktrees");
  const branchPrefix = opts.branchPrefix ?? "improve";
  return {
    async create({ baseRef, label }) {
      const id = `${slug(label)}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`;
      const branch = `${branchPrefix}/${id}`;
      const path = join3(worktreeDir, id);
      git(["worktree", "add", "-b", branch, path, baseRef], opts.repoRoot);
      return { path, branch, baseRef };
    },
    async finalize(worktree, summary) {
      const status = git(["status", "--porcelain"], worktree.path);
      if (status.length > 0) {
        git(["add", "-A"], worktree.path);
        git(["commit", "-m", summary], worktree.path);
      }
      return {
        kind: "code",
        worktreeRef: worktree.path,
        baseRef: worktree.baseRef,
        summary
      };
    },
    async discard(worktree) {
      git(["worktree", "remove", "--force", worktree.path], opts.repoRoot);
      git(["branch", "-D", worktree.branch], opts.repoRoot);
    }
  };
}
function resolveWorktreePath(surface, worktreeDir) {
  if (isAbsolute(surface.worktreeRef) && existsSync2(surface.worktreeRef)) return surface.worktreeRef;
  if (worktreeDir) return join3(worktreeDir, basename(surface.worktreeRef));
  return surface.worktreeRef;
}
export {
  FsLabeledScenarioStore,
  LabeledScenarioStoreError,
  ProfileMatrixError,
  WorktreeAdapterError,
  buildLoopProvenanceRecord,
  composeGate,
  countSentenceEdits,
  defaultProductionGate,
  defaultRenderDiff,
  emitLoopProvenance,
  evolutionaryDriver,
  extractH2Sections,
  fsCampaignStorage,
  gepaDriver,
  gitWorktreeAdapter,
  heldOutGate,
  inMemoryCampaignStorage,
  isProposedCandidate,
  labelTrustRank,
  loopProvenanceSpans,
  openAutoPr,
  provenanceRecordPath,
  provenanceSpansPath,
  resolveWorktreePath,
  runCampaign,
  runEval,
  runImprovementLoop,
  runOptimization,
  runProfileMatrix,
  surfaceContentHash,
  surfaceHash
};
//# sourceMappingURL=index.js.map