import {
  composeGate,
  countSentenceEdits,
  defaultProductionGate,
  evolutionaryDriver,
  extractH2Sections,
  gepaDriver,
  heldOutGate,
  openAutoPr,
  runEval,
  runImprovementLoop,
  runOptimization,
  surfaceHash
} from "../chunk-JB4UWIM6.js";
import {
  fsCampaignStorage,
  inMemoryCampaignStorage,
  runCampaign
} from "../chunk-74Y2EMNH.js";
import "../chunk-N4SBKEPJ.js";
import "../chunk-YV7J7X5N.js";
import "../chunk-S3SDD56V.js";
import "../chunk-GGE4NNQT.js";
import "../chunk-VXNVVBZO.js";
import "../chunk-PC4UYEBM.js";
import "../chunk-QYJT52YW.js";
import "../chunk-NSBPE2FW.js";

// src/campaign/labeled-store/fs-adapter.ts
import { createHash } from "crypto";
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
import { join } from "path";

// src/campaign/types.ts
var LABEL_TRUST_RANK = {
  unverified: 0,
  "verified-signal": 1,
  "human-rated": 2
};
function labelTrustRank(trust) {
  return LABEL_TRUST_RANK[trust ?? "unverified"];
}

// src/campaign/labeled-store/fs-adapter.ts
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/worktree/index.ts
import { execFileSync } from "child_process";
import { existsSync as existsSync2 } from "fs";
import { basename, isAbsolute, join as join2 } 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 ?? join2(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 = join2(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 join2(worktreeDir, basename(surface.worktreeRef));
  return surface.worktreeRef;
}
export {
  FsLabeledScenarioStore,
  LabeledScenarioStoreError,
  WorktreeAdapterError,
  composeGate,
  countSentenceEdits,
  defaultProductionGate,
  evolutionaryDriver,
  extractH2Sections,
  fsCampaignStorage,
  gepaDriver,
  gitWorktreeAdapter,
  heldOutGate,
  inMemoryCampaignStorage,
  labelTrustRank,
  openAutoPr,
  resolveWorktreePath,
  runCampaign,
  runEval,
  runImprovementLoop,
  runOptimization,
  surfaceHash
};
//# sourceMappingURL=index.js.map