import { a as RunCampaignOptions, C as CampaignStorage } from '../provenance-lqyLpOYR.js';
export { B as BuildLoopProvenanceArgs, D as DefaultProductionGateOptions, m as EmitLoopProvenanceArgs, n as EmitLoopProvenanceResult, E as EvolutionaryDriverOptions, o as GepaDriverConstraints, G as GepaDriverOptions, H as HeldOutGateOptions, p as LoopProvenanceBackend, q as LoopProvenanceCandidate, L as LoopProvenanceRecord, O as OpenAutoPrOptions, s as OpenAutoPrResult, b as RunEvalOptions, c as RunImprovementLoopOptions, R as RunImprovementLoopResult, t as RunOptimizationOptions, u as RunOptimizationResult, v as buildLoopProvenanceRecord, d as composeGate, w as countSentenceEdits, e as defaultProductionGate, x as defaultRenderDiff, y as emitLoopProvenance, f as evolutionaryDriver, z as extractH2Sections, g as fsCampaignStorage, h as gepaDriver, i as heldOutGate, j as inMemoryCampaignStorage, A as loopProvenanceSpans, F as openAutoPr, I as provenanceRecordPath, J as provenanceSpansPath, r as runCampaign, k as runEval, l as runImprovementLoop, K as runOptimization, M as surfaceContentHash, N as surfaceHash } from '../provenance-lqyLpOYR.js';
import { L as LlmClientOptions } from '../llm-client-DbjLfz-K.js';
import { I as ImprovementDriver, L as LabeledScenarioStore, q as LabeledScenarioWrite, r as LabeledScenarioSampleArgs, s as LabeledScenarioRecord, t as LabelTrust, S as Scenario, M as MutableSurface, b as DispatchContext, a as JudgeConfig, u as LabeledScenarioSource, f as CampaignResult, h as CodeSurface } from '../types-c2R2kfmv.js';
export { C as CampaignAggregates, c as CampaignArtifactWriter, d as CampaignCellResult, e as CampaignCostMeter, v as CampaignTokenUsage, g as CampaignTraceWriter, D as DispatchFn, G as Gate, i as GateContext, j as GateDecision, k as GateResult, l as GenerationCandidate, m as GenerationRecord, w as JudgeAggregate, n as JudgeDimension, J as JudgeScore, o as Mutator, O as OptimizerConfig, P as ParetoParent, x as ProposeContext, y as ProposedCandidate, R as RedactionStatus, z as ScenarioAggregate, p as SessionScript, T as TraceSpan, A as isProposedCandidate, B as labelTrustRank } from '../types-c2R2kfmv.js';
import { A as AgentProfile, B as BackendIntegrityReport } from '../agent-profile-DzcPHR1Z.js';
import { A as AgentEvalError } from '../errors-Dwqw-T_m.js';
import { b as RunSplitTag, R as RunRecord } from '../run-record-BgTFzO2r.js';
import '../red-team-DW9Ca_tj.js';
import '../dataset-B2kL-fSM.js';
import '../store-CKUAgsJz.js';
import '../schema-m0gsnbt3.js';
import '../index-CzhtwYBT.js';
import '../summary-report-ByiOUrHj.js';
import '../failure-cluster-CL7IVgkJ.js';
import '../judge-calibration-DilmB3Ml.js';
import '../raw-provider-sink-C46HDghv.js';

/**
 * @experimental
 *
 * SkillOpt patch primitives (Microsoft, arXiv:2605.23904 — "Executive
 * Strategy for Self-Evolving Agent Skills"). Where GEPA regenerates a surface
 * by reflection, SkillOpt emits BOUNDED, anchored edits to ONE skill document
 * — add / delete / replace — and accepts an edit only if it strictly improves
 * a held-out score. Bounded edits are the "textual learning rate": small,
 * reversible, and cheap to accept/reject, so a good rule introduced earlier is
 * not overwritten by a later sweeping rewrite.
 *
 * This module applies a patch deterministically and reports, per op, what
 * applied and what could not (a missing anchor is a rejected op, never a
 * silently dropped one). Pure, no I/O.
 */
/** A single bounded edit against a skill surface.
 *   - `add`     — insert `text` after the first line containing `after`
 *                 (append to the end when `after` is absent/empty).
 *   - `delete`  — remove the first line containing `anchor`.
 *   - `replace` — replace the first line containing `anchor` with `text`.
 *  `text` may be multi-line; it is spliced in as multiple lines. Anchors match
 *  the FIRST line that contains the substring (deterministic; SkillOpt is
 *  expected to anchor on unique text). */
type SkillPatchOp = {
    op: 'add';
    after?: string;
    text: string;
} | {
    op: 'delete';
    anchor: string;
} | {
    op: 'replace';
    anchor: string;
    text: string;
};
/** A named, attributable bundle of ops the optimizer proposes as one edit. */
interface SkillPatch {
    label: string;
    rationale: string;
    ops: SkillPatchOp[];
}
interface SkillPatchRejection {
    op: SkillPatchOp;
    reason: string;
}
interface ApplySkillPatchResult {
    surface: string;
    /** Count of ops that mutated the surface. */
    applied: number;
    /** Ops that could not apply (unanchored / empty), with the reason. The
     *  surface still reflects every APPLIED op — partial application is honest,
     *  and the caller decides whether a partial patch is worth scoring. */
    rejected: SkillPatchRejection[];
}
/**
 * Apply a SkillOpt patch to a text surface. Ops apply in array order against
 * the evolving line buffer (an `add after X` followed by a `delete X` sees the
 * inserted lines). A missing anchor rejects only that op; the rest still apply.
 */
declare function applySkillPatch(surface: string, patch: SkillPatch): ApplySkillPatchResult;
/** Total ops in a patch — the edit-budget axis (SkillOpt's "textual learning
 *  rate" caps this per epoch). */
declare function patchEditCount(patch: SkillPatch): number;

/**
 * @experimental
 *
 * `skillOptDriver` — a patch-mode `ImprovementDriver` implementing SkillOpt
 * (Microsoft, arXiv:2605.23904). Where `gepaDriver` regenerates the whole
 * surface by reflection, SkillOpt proposes BOUNDED, anchored edits
 * (add/delete/replace) to ONE skill document, so a good rule introduced
 * earlier is not clobbered by a later sweeping rewrite. The edit budget is the
 * paper's "textual learning rate"; a rejected-edit buffer + a slow-update
 * meta-note steer the optimizer away from dead ends.
 *
 * This module is the PROPOSER — the LLM call that turns evidence into
 * structured patches. The accept-only-if-held-out-improves loop, the budget
 * annealing, and the rejected buffer live in the `runSkillOpt` preset, which
 * owns the epoch hill-climb. The driver also conforms to `ImprovementDriver`
 * (`propose` applies its patches to the current surface and returns the
 * candidate surfaces) so it is a drop-in for `runOptimization` and a fair
 * entrant in `compareDrivers`.
 */

/** Evidence the optimizer reflects on: where the current surface is weakest.
 *  Computed by the caller (the preset uses a TRAIN campaign so proposals never
 *  see the held-out split; the generic loop derives it from history). */
interface SkillOptEvidence {
    /** Lowest-scoring scenarios (drives WHICH behavior to patch). */
    weakScenarios: Array<{
        scenarioId: string;
        composite: number;
    }>;
    /** Lowest-scoring judge dimensions (drives WHAT to patch for). */
    weakDimensions: Array<{
        dimension: string;
        score: number;
    }>;
}
/** A patch that was tried and not accepted — fed back to the model so it does
 *  not re-propose a dead end (SkillOpt's rejected-edit buffer). */
interface RejectedEdit {
    label: string;
    rationale: string;
    reason: string;
}
interface ProposePatchesArgs {
    surface: string;
    evidence: SkillOptEvidence;
    /** Max ops per patch this round (the annealed textual learning rate). */
    editBudget: number;
    rejectedBuffer: RejectedEdit[];
    /** Slow-update meta guidance accumulated across epochs. */
    metaNote?: string;
    /** How many candidate patches to propose. */
    count: number;
    signal: AbortSignal;
}
interface SkillOptDriverOptions {
    llm: LlmClientOptions;
    model: string;
    /** What the skill document governs — orients the prompt. */
    target: string;
    /** Default ops-per-patch cap when used as a bare `ImprovementDriver`. The
     *  `runSkillOpt` preset overrides this per epoch as it anneals. Default 3. */
    editBudget?: number;
    temperature?: number;
    maxTokens?: number;
    /** Top-K weak scenarios/dimensions surfaced as evidence. Default 3. */
    evidenceK?: number;
}
interface SkillOptDriver extends ImprovementDriver {
    /** Patch-native path used by `runSkillOpt` (the SkillOpt epoch loop owns
     *  acceptance/budget/buffer). Returns structured patches, NOT surfaces. */
    proposePatches(args: ProposePatchesArgs): Promise<SkillPatch[]>;
}
declare function skillOptDriver(opts: SkillOptDriverOptions): SkillOptDriver;
/** Parse + validate the patch response. Throws `SkillPatchParseError` when the
 *  response is not valid JSON at all (a router/model failure the caller must
 *  see — never a silent no-op epoch). Returns `[]` only for the legitimate
 *  "valid JSON, zero usable patches" case. Malformed ops within a patch are
 *  dropped (not silently mutated); each patch is truncated to the edit budget. */
declare class SkillPatchParseError extends Error {
    constructor(message: string);
}
declare function parseSkillPatchResponse(raw: string, maxPatches: number, editBudget: number): SkillPatch[];

/**
 * @experimental
 *
 * Filesystem `LabeledScenarioStore` adapter. The default capture sink for
 * traces + eval artifacts. Production deployments typically swap for a
 * Turso/SQLite adapter (same interface).
 *
 * Records land as one JSONL file per source under `<root>/<source>.jsonl`.
 * Each line is a `LabeledScenarioRecord`. Append-only — no in-place edits.
 *
 * Safety properties enforced at write-time:
 *
 *   - **Provenance required**: writes without `source`, `sourceVersionHash`,
 *     `capturedAt`, `redactionStatus` are rejected. Closes the alignment
 *     reviewer's data-poisoning gap.
 *   - **Per-source rate limits**: optional `rateLimitBucket` + `maxWritesPerMinute`
 *     stops a single tenant/source from flooding the store.
 *
 * Safety properties enforced at sample-time:
 *
 *   - **Required split + capturedBefore**: substrate refuses to sample without
 *     an explicit `split` ('train' | 'test') AND a temporal cutoff. Eliminates
 *     accidental train/test contamination.
 *   - **Default training-source filter**: when the store is sampled with
 *     `split: 'train'`, production-trace records are EXCLUDED unless the
 *     caller passes `filter.source: 'production-trace'` explicitly. Closes
 *     the contamination-by-default gap flagged by the senior eval engineer.
 */

interface FsLabeledScenarioStoreOptions {
    /** Root directory for JSONL files. Created if missing. */
    root: string;
    /** Per-source rate limit. When set, writes exceeding the cap are rejected
     *  with a typed error. Default: no limit. */
    maxWritesPerMinutePerBucket?: number;
    /** Test seam — override `Date.now()` for deterministic tests. */
    now?: () => number;
}
declare class LabeledScenarioStoreError extends Error {
    readonly code: string;
    constructor(code: string, message: string);
}
declare class FsLabeledScenarioStore implements LabeledScenarioStore {
    private readonly options;
    private readonly now;
    private readonly rateLimits;
    constructor(options: FsLabeledScenarioStoreOptions);
    observe(write: LabeledScenarioWrite): Promise<void>;
    sample(args: LabeledScenarioSampleArgs): Promise<LabeledScenarioRecord[]>;
    size(): Promise<{
        train: number;
        test: number;
        bySource: Record<string, number>;
        byTrust: Record<LabelTrust, number>;
    }>;
    private assertProvenance;
    private assertRateLimit;
    private toRecord;
    private pathForSource;
}

/**
 * @experimental
 *
 * `compareDrivers` — a head-to-head lift benchmark across optimizer drivers on
 * ONE corpus. This is the forcing function: optimizer quality (GEPA reflection
 * vs GEPA+Pareto vs SkillOpt) becomes a NUMBER with a confidence interval, so a
 * driver regression — or shipping a simplified driver and calling it the real
 * one — turns a build red instead of going measurement-invisible.
 *
 * Every entrant is scored the SAME way: each driver returns the surface it
 * promoted, then `compareDrivers` scores the baseline + every winner on the
 * SAME held-out scenarios with the SAME judges. Apples-to-apples by
 * construction — the comparison never depends on how a driver measured itself.
 * The per-scenario held-out composites feed a paired bootstrap (`statistics.ts`)
 * for each driver's lift CI and for the pairwise "which driver wins" CI.
 */

/** What an optimizer produced: the surface it promoted + what it cost to get
 *  there. `compareDrivers` does the held-out scoring itself, so an entry only
 *  needs to run its loop and hand back the winner. */
interface DriverEntry {
    name: string;
    optimize: () => Promise<{
        winnerSurface: MutableSurface;
        costUsd: number;
        durationMs?: number;
    }>;
}
interface DriverScore {
    name: string;
    /** Mean held-out composite of the baseline (identical across drivers). */
    baselineComposite: number;
    /** Mean held-out composite of this driver's promoted surface. */
    winnerComposite: number;
    /** Mean per-scenario held-out lift (winner − baseline). */
    lift: number;
    /** Paired-bootstrap CI of the per-scenario lift. `low > 0` ⇒ a real gain. */
    liftCi: {
        low: number;
        high: number;
    };
    costUsd: number;
    durationMs?: number;
    winnerSurface: MutableSurface;
    /** 1-based, by descending lift. */
    rank: number;
}
interface DriverPairwise {
    /** Higher-ranked driver. */
    a: string;
    b: string;
    /** Mean per-scenario held-out delta (a − b). */
    deltaMean: number;
    low: number;
    high: number;
    /** `a` if the CI clears 0, `b` if it is entirely negative, else `'tie'`. */
    favored: string;
}
interface DriverComparison {
    /** Sorted by descending lift; `rank` set accordingly. */
    scores: DriverScore[];
    best: DriverScore;
    /** Best vs each other driver, paired-bootstrap on the held-out winners. */
    pairwise: DriverPairwise[];
    holdoutScenarioIds: string[];
}
interface CompareDriversOptions<TScenario extends Scenario, TArtifact> extends Omit<RunCampaignOptions<TScenario, TArtifact>, 'dispatch' | 'scenarios'> {
    drivers: DriverEntry[];
    baselineSurface: MutableSurface;
    /** The held-out scenarios every winner is scored on. */
    holdoutScenarios: TScenario[];
    /** Scores a surface on a scenario — the same dispatcher the drivers used. */
    dispatchWithSurface: (surface: MutableSurface, scenario: TScenario, ctx: DispatchContext) => Promise<TArtifact>;
    /** Bootstrap resamples for the lift CIs. Default 2000. */
    resamples?: number;
    /** CI confidence. Default 0.95. */
    confidence?: number;
}
declare function compareDrivers<TScenario extends Scenario, TArtifact>(opts: CompareDriversOptions<TScenario, TArtifact>): Promise<DriverComparison>;
/** Shared corpus + transport for the three built-in optimizer entries. */
interface OptimizerEntryConfig<TScenario extends Scenario, TArtifact> {
    baselineSurface: string;
    /** Training scenarios the drivers reflect on. */
    trainScenarios: TScenario[];
    /** Held-out scenarios (the gate axis + the benchmark scoring axis). */
    holdoutScenarios: TScenario[];
    dispatchWithSurface: (surface: MutableSurface, scenario: TScenario, ctx: DispatchContext) => Promise<TArtifact>;
    judges: JudgeConfig<TArtifact, TScenario>[];
    llm: LlmClientOptions;
    model: string;
    target: string;
    runDir: string;
    seed?: number;
    /** GEPA population per generation. Default 2. */
    populationSize?: number;
    /** GEPA generations. Default 3. */
    maxGenerations?: number;
    /** SkillOpt epochs. Default 6. */
    maxEpochs?: number;
    mutationPrimitives?: string[];
}
/** GEPA, reflection-only (single-parent, no Pareto combine). */
declare function gepaReflectionEntry<TScenario extends Scenario, TArtifact>(config: OptimizerEntryConfig<TScenario, TArtifact>, name?: string): DriverEntry;
/** GEPA with the Pareto frontier + combine-complementary-lessons. */
declare function gepaParetoEntry<TScenario extends Scenario, TArtifact>(config: OptimizerEntryConfig<TScenario, TArtifact>, name?: string): DriverEntry;
/** SkillOpt patch-mode hill-climb. */
declare function skillOptEntry<TScenario extends Scenario, TArtifact>(config: OptimizerEntryConfig<TScenario, TArtifact>, name?: string): DriverEntry;

/**
 * @experimental
 *
 * `runProfileMatrix` — the missing keystone between `runAgentMatrix` and the
 * backend-integrity guard.
 *
 * The gap it closes: `runAgentMatrix` is a topology-opaque scheduler whose
 * cells return a bare `{ output, verdict, costUsd }` — no `tokenUsage`, not a
 * `RunRecord`. `assertRealBackend` / `summarizeBackendIntegrity` key on
 * `RunRecord.tokenUsage`, so they cannot run on a raw matrix result. Every
 * consumer therefore hand-writes the same bridge: fan a profile × scenario
 * cartesian, call dispatch, fabricate a `RunRecord` with token usage, thread it
 * back, run the integrity guard. That hand-rolled bridge is exactly the pile of
 * bespoke `eval:*` scripts the adoption skills keep trying (and failing) to
 * forbid.
 *
 * `runProfileMatrix` IS that bridge, once:
 *
 *   - axis 3 (PROFILE) = `profiles: AgentProfile[]`
 *   - axis 1 (PERSONA/SCENARIO) = `scenarios: Scenario[]` (each scenario carries
 *     its persona; `personaOf` groups them for the `byPersona` pivot)
 *   - the scoring axis = `judges`
 *
 * It runs `runCampaign` once per profile (reusing its seeds, reps, bootstrap
 * CIs, resumability, and the `LabeledScenarioStore` capture flywheel), maps
 * every cell to a validated `RunRecord` carrying the real `tokenUsage` the
 * dispatch reported via `ctx.cost.observeTokens`, and runs `assertRealBackend`
 * BY CONSTRUCTION before returning — so a stub-backend run fails loudly instead
 * of reporting a clean 0/N leaderboard.
 *
 * Dispatch contract: a dispatch that calls an LLM MUST report usage via
 * `ctx.cost.observeTokens({ input, output })` (and cost via `ctx.cost.observe`).
 * A dispatch that reports zero tokens is indistinguishable from a stub and the
 * integrity guard treats it as one.
 */

/** Thrown when the matrix is misconfigured (no profiles, a profile whose model
 *  lacks a snapshot version, etc.). Distinct from `BackendIntegrityError`,
 *  which signals a stub backend at run time. */
declare class ProfileMatrixError extends AgentEvalError {
    constructor(message: string);
}
/** Dispatch for one cell: render `profile` against `scenario`, returning the
 *  artifact the judges score. Report LLM usage via `ctx.cost.observeTokens`
 *  and `ctx.cost.observe` — the integrity guard depends on it. */
type ProfileDispatchFn<TScenario extends Scenario, TArtifact> = (profile: AgentProfile, scenario: TScenario, ctx: DispatchContext) => Promise<TArtifact>;
interface RunProfileMatrixOptions<TScenario extends Scenario, TArtifact> {
    /** Axis 3 — the agent-under-test configurations. Each is one column. */
    profiles: AgentProfile[];
    /** Axis 1 — the persona/scenario corpus, run against every profile. */
    scenarios: TScenario[];
    /** Renders one (profile, scenario) cell. */
    dispatch: ProfileDispatchFn<TScenario, TArtifact>;
    /** The scoring axis. */
    judges?: JudgeConfig<TArtifact, TScenario>[];
    /** Where each profile's campaign writes artifacts/traces. One subdir per
     *  profile. */
    runDir: string;
    /** Git SHA the harness ran from — stamped onto every RunRecord (mandatory
     *  for paper-grade records). */
    commitSha: string;
    /** Logical experiment id shared across the whole matrix so the promotion
     *  gate can pair profiles on matched scenarios. Default: a hash of the
     *  profile + scenario ids. */
    experimentId?: string;
    /** Which split these runs belong to. Default `'search'`. */
    splitTag?: RunSplitTag;
    /** Replicates per (profile, scenario) cell for CI bands. Default 1. */
    reps?: number;
    /** Campaign seed (per profile). Default 42. */
    seed?: number;
    /**
     * Backend-integrity posture, enforced AFTER the matrix completes:
     *   - `'assert'` (default) — throw `BackendIntegrityError` if the run was a
     *     stub (and, with `allowMixed:false`, if it was mixed).
     *   - `'warn'` — log the verdict but never throw.
     *   - `'off'` — skip the guard entirely (only for offline/replay analysis).
     */
    integrity?: 'assert' | 'warn' | 'off';
    /** Forwarded to `assertRealBackend`. Default true (tolerate partial 429
     *  cascades); set false for strict CI gates. */
    allowMixed?: boolean;
    /** Max concurrent cells WITHIN each profile's campaign. Default 2.
     *  Profiles run sequentially so the cost ceiling is honored deterministically. */
    maxConcurrency?: number;
    /** Cumulative USD cap per profile campaign. */
    costCeiling?: number;
    /** Capture flywheel — forwarded to each campaign. */
    labeledStore?: LabeledScenarioStore | 'off';
    captureSource?: LabeledScenarioSource;
    /** Storage backend. Default `fsCampaignStorage`. Pass
     *  `inMemoryCampaignStorage()` for edge/CF-Worker/test runs. */
    storage?: CampaignStorage;
    /** Test seam — override the wall clock. */
    now?: () => Date;
    /** Optional persona key per scenario — drives the `byPersona` pivot. When
     *  unset, `byPersona` is omitted. */
    personaOf?: (scenario: TScenario) => string;
    /** Validate every produced RunRecord with `validateRunRecord` (fail-loud).
     *  Default true — catches bad model snapshots and non-finite judge dims at
     *  the boundary instead of letting them poison downstream analysis. */
    validate?: boolean;
}
interface ProfileSummary {
    profileId: string;
    profileHash: string;
    model: string;
    /** RunRecords produced for this profile (= scenarios × reps). */
    records: number;
    /** Mean composite across this profile's records. */
    meanComposite: number;
    totalCostUsd: number;
    /** Per-profile integrity verdict — surfaces a single profile that ran stub
     *  even when the matrix as a whole looks real. */
    integrity: BackendIntegrityReport;
}
interface ScenarioRollup {
    meanComposite: number;
    n: number;
}
interface RunProfileMatrixResult<TArtifact, TScenario extends Scenario> {
    matrixId: string;
    experimentId: string;
    /** One RunRecord per (profile, scenario, rep) cell — the integrity-checked,
     *  paper-grade output. Feed straight into `analyzeRuns`, `HeldOutGate`,
     *  scorecards, the hosted wire format. */
    records: RunRecord[];
    byProfile: Record<string, ProfileSummary>;
    byScenario: Record<string, ScenarioRollup>;
    /** Present only when `personaOf` was supplied. */
    byPersona?: Record<string, ScenarioRollup>;
    /** Whole-matrix integrity report (the one `integrity:'assert'` enforces). */
    integrity: BackendIntegrityReport;
    /** The raw per-profile campaign results, keyed by profile id. */
    campaigns: Record<string, CampaignResult<TArtifact, TScenario>>;
}
declare function runProfileMatrix<TScenario extends Scenario, TArtifact>(opts: RunProfileMatrixOptions<TScenario, TArtifact>): Promise<RunProfileMatrixResult<TArtifact, TScenario>>;

/**
 * @experimental
 *
 * `runSkillOpt` — the SkillOpt epoch hill-climb (Microsoft, arXiv:2605.23904).
 * Unlike `runOptimization`'s population/promote-top-K search, SkillOpt is a
 * sequential, held-out-gated hill-climb on ONE skill document:
 *
 *   each epoch:
 *     1. reflect on the CURRENT surface's weakest TRAIN scenarios/dimensions
 *        (never the held-out split — proposals must not see the acceptance axis)
 *     2. propose ≤ `patchesPerEpoch` bounded patches (≤ `editBudget` ops each)
 *     3. apply each; score the candidate on the HELD-OUT split
 *     4. ACCEPT the first patch that STRICTLY improves the held-out composite;
 *        otherwise push it to the rejected-edit buffer (fed back so the model
 *        does not re-propose dead ends)
 *     5. anneal the edit budget down after consecutive rejections (the
 *        "textual learning rate" decay); refresh the slow-update meta note
 *     6. stop at `maxEpochs` or after `patience` epochs with no acceptance
 *
 * The accept-only-if-held-out-improves rule is the same discipline as
 * `HeldOutGate`/`defaultProductionGate`, applied per edit instead of once at
 * the end — which is why the held-out composite is monotonically
 * non-decreasing and a regression can never ship. `runCampaign` is the
 * measurement; `applySkillPatch` applies the edits; `skillOptDriver` proposes
 * them.
 */

interface RunSkillOptOptions<TScenario extends Scenario, TArtifact> extends Omit<RunCampaignOptions<TScenario, TArtifact>, 'dispatch' | 'scenarios'> {
    /** The skill document being optimized. */
    baselineSurface: string;
    /** Dispatcher taking the CURRENT skill surface + scenario → artifact. */
    dispatchWithSurface: (surface: string, scenario: TScenario, ctx: DispatchContext) => Promise<TArtifact>;
    driver: SkillOptDriver;
    /** Scenarios the optimizer reflects on for evidence. MUST be disjoint from
     *  `holdoutScenarios` — proposals never see the acceptance axis. */
    trainScenarios: TScenario[];
    /** Held-out scenarios. An edit is accepted ONLY if it strictly improves the
     *  mean composite here. */
    holdoutScenarios: TScenario[];
    maxEpochs: number;
    /** Candidate patches proposed per epoch. Default 2. */
    patchesPerEpoch?: number;
    /** Initial ops-per-patch cap (the textual learning rate). Default 3. */
    editBudget?: number;
    /** Strict acceptance margin: accept iff the held-out composite improves by
     *  MORE than this. Default 0 (any strict improvement). */
    minImprovement?: number;
    /** Stop after this many consecutive epochs with no acceptance. Default =
     *  `maxEpochs` (never early-stop). */
    patience?: number;
    /** Shrink the edit budget by 1 after 2 consecutive rejected epochs (min 1).
     *  Default true. */
    budgetAnneal?: boolean;
    /** Cap on the rejected-edit buffer (most-recent kept). Default 12. */
    rejectedBufferSize?: number;
    /** Refresh the slow-update meta note every N epochs. Default 2. 0 disables. */
    slowMetaEvery?: number;
    /** Top-K weak scenarios/dimensions surfaced as evidence each epoch. Default 3. */
    evidenceK?: number;
    /** Abort signal forwarded to the patch-proposing LLM calls. */
    signal?: AbortSignal;
}
interface AcceptedEdit {
    epoch: number;
    label: string;
    rationale: string;
    /** Held-out composite improvement vs the surface before this edit. */
    holdoutDelta: number;
}
interface SkillOptEpochRecord {
    epoch: number;
    editBudget: number;
    proposed: number;
    /** The accepted edit this epoch, or null if every proposal was rejected. */
    accepted: AcceptedEdit | null;
    rejected: RejectedEdit[];
    /** Held-out composite of the CURRENT surface at the END of the epoch. */
    holdoutComposite: number;
}
interface RunSkillOptResult {
    winnerSurface: string;
    baselineHoldoutComposite: number;
    winnerHoldoutComposite: number;
    /** `winnerHoldoutComposite - baselineHoldoutComposite` — monotonically ≥ 0
     *  by construction (only strictly-improving edits are accepted). */
    lift: number;
    acceptedEdits: AcceptedEdit[];
    rejectedEdits: RejectedEdit[];
    epochsRun: number;
    history: SkillOptEpochRecord[];
    /** Total cost across every scoring campaign (train evidence + holdout
     *  acceptance) the hill-climb ran. */
    totalCostUsd: number;
}
declare function runSkillOpt<TScenario extends Scenario, TArtifact>(opts: RunSkillOptOptions<TScenario, TArtifact>): Promise<RunSkillOptResult>;

/**
 * @experimental
 *
 * Shared campaign-score reductions used by every optimizer preset
 * (`runOptimization`, `runSkillOpt`, `compareDrivers`). ONE definition of
 * "composite of a campaign" and "per-scenario / per-dimension breakdown" so
 * the optimizers cannot drift on how a surface's score is computed.
 */

/** Mean composite across a campaign: per cell, the mean of its judges'
 *  composites; then the mean across cells. Cells with no judge scores are
 *  skipped. Empty ⇒ 0. */
declare function campaignMeanComposite<TArtifact, TScenario extends Scenario>(campaign: CampaignResult<TArtifact, TScenario>): number;
interface CampaignBreakdown {
    /** Mean score per judge dimension across all cells. */
    dimensions: Record<string, number>;
    /** Per-scenario composite (mean over reps + judges). */
    scenarios: Array<{
        scenarioId: string;
        composite: number;
    }>;
}
/** Per-candidate evidence a reflective/patch driver grounds its next proposal
 *  on: mean score per judge dimension + per-scenario composite. */
declare function campaignBreakdown<TArtifact, TScenario extends Scenario>(campaign: CampaignResult<TArtifact, TScenario>): CampaignBreakdown;

/**
 * @experimental
 *
 * VCS-pluggable worktree adapter. One improvement = one worktree, PR-like
 * (multiple commits allowed). A code-tier driver's `propose()` creates a
 * worktree, an agent commits the change into it, and `finalize()` returns a
 * `CodeSurface{ worktreeRef }` the measurement checks out to run the worker
 * against the changed code. On promotion the worktree becomes the PR branch.
 *
 * The interface is VCS-agnostic so a future `jj` ([jj-vcs](https://github.com/jj-vcs/jj))
 * adapter can slot in without touching driver code. Only the git adapter
 * ships today. See `docs/design/self-improvement-engine.md`.
 */

interface Worktree {
    /** Absolute path to the checked-out worktree directory. */
    path: string;
    /** The branch the worktree is on (becomes the PR branch on promotion). */
    branch: string;
    /** The ref the worktree was forked from. */
    baseRef: string;
}
interface WorktreeAdapter {
    /** Create an isolated worktree on a fresh branch off `baseRef`. */
    create(opts: {
        baseRef: string;
        label: string;
    }): Promise<Worktree>;
    /** Commit any pending changes in the worktree, then return a CodeSurface
     *  pointing at it. The agent has already written its change into
     *  `worktree.path` by the time this is called. */
    finalize(worktree: Worktree, summary: string): Promise<CodeSurface>;
    /** Remove the worktree (and its branch) — called for losing candidates. */
    discard(worktree: Worktree): Promise<void>;
}
declare class WorktreeAdapterError extends Error {
    readonly cause?: unknown | undefined;
    constructor(message: string, cause?: unknown | undefined);
}
interface GitWorktreeAdapterOptions {
    /** Repo root the worktrees fork from. */
    repoRoot: string;
    /** Directory worktrees are created under. Default: `<repoRoot>/.worktrees`. */
    worktreeDir?: string;
    /** Branch-name prefix. Default: `improve`. */
    branchPrefix?: string;
    /** Test seam — defaults to a real `git` runner. */
    git?: (args: string[], cwd: string) => string;
}
declare function gitWorktreeAdapter(opts: GitWorktreeAdapterOptions): WorktreeAdapter;
/** Resolve a `CodeSurface`'s worktreeRef to a directory the measurement can
 *  run the worker in. A path ref is returned as-is; anything else is treated
 *  as a ref under the adapter's worktree dir. */
declare function resolveWorktreePath(surface: CodeSurface, worktreeDir?: string): string;

export { type AcceptedEdit, type ApplySkillPatchResult, type CampaignBreakdown, CampaignResult, CampaignStorage, CodeSurface, type CompareDriversOptions, DispatchContext, type DriverComparison, type DriverEntry, type DriverPairwise, type DriverScore, FsLabeledScenarioStore, type FsLabeledScenarioStoreOptions, type GitWorktreeAdapterOptions, ImprovementDriver, JudgeConfig, LabelTrust, LabeledScenarioRecord, LabeledScenarioSampleArgs, LabeledScenarioSource, LabeledScenarioStore, LabeledScenarioStoreError, LabeledScenarioWrite, MutableSurface, type OptimizerEntryConfig, type ProfileDispatchFn, ProfileMatrixError, type ProfileSummary, type ProposePatchesArgs, type RejectedEdit, RunCampaignOptions, type RunProfileMatrixOptions, type RunProfileMatrixResult, type RunSkillOptOptions, type RunSkillOptResult, Scenario, type ScenarioRollup, type SkillOptDriver, type SkillOptDriverOptions, type SkillOptEpochRecord, type SkillOptEvidence, type SkillPatch, type SkillPatchOp, SkillPatchParseError, type SkillPatchRejection, type Worktree, type WorktreeAdapter, WorktreeAdapterError, applySkillPatch, campaignBreakdown, campaignMeanComposite, compareDrivers, gepaParetoEntry, gepaReflectionEntry, gitWorktreeAdapter, parseSkillPatchResponse, patchEditCount, resolveWorktreePath, runProfileMatrix, runSkillOpt, skillOptDriver, skillOptEntry };
