/** * The arm probe — seeded runs in, shared statistics out. * * Split in two on purpose. `collectArmRuns` only RUNS (it cannot know the * reference yet: when no prior answer was supplied, the reference IS the * baseline arm's first answer). `scoreArmRuns` only SCORES. Keeping them apart * is what lets the reference be chosen between the two halves without a second * pass over the model — the same "one ablation, two readouts" thrift * `runAblationProbe` applies to cost. * * Everything statistical is borrowed, not re-derived: `similarityStats`, * `costStatsFrom` and `resolveSamples` come from `ablation.ts` unchanged, so an * arm's `AblationRunStats` is the same number computed the same way as an * ablation's — which is the point of sharing the statistics while keeping the * spec types apart. */ import type { AblationRunStats, Embedder, OutcomeComparator } from '../types.js'; import type { ArmApplication, ArmRunner, NullBand, RunManifestLike, StrategyArm } from './types.js'; /** The raw harvest of one arm's seeded runs — no scoring yet. */ export interface ArmRuns { readonly answers: readonly string[]; readonly loops: readonly number[]; readonly tokens: readonly number[]; readonly manifests: readonly RunManifestLike[]; } /** * Call the consumer's runner once per seed (0..samples-1) for ONE arm and * normalize the two return shapes (`string` | `{output, cost?, manifest?}`) — * the same normalization `runAblationProbe` performs, so a bare-string runner * costs the caller nothing in ceremony. */ export declare function collectArmRuns(arm: StrategyArm, runner: ArmRunner, samples: number): Promise; /** * Score one arm's harvested answers against the reference: similarity per seed * (mean/min/max/stdev) plus the outcome-flip count. Shape-identical to what an * ablation probe reports. */ export declare function scoreArmRuns(runs: ArmRuns, reference: string, embedder: Embedder, outcomeChanged: OutcomeComparator): Promise; /** * Build the inert-intervention control from the baseline arm's OWN seeded runs. * See {@link NullBand} for why leave-one-out does not transfer and this does. */ export declare function nullBandFrom(baselineArmId: string, baselineStats: AblationRunStats, gates: boolean): NullBand; /** * Did this arm actually take effect? Compares every manifest the runner * reported against the arm's declared facets. * * `checked: false` — and therefore no refusal — in exactly two cases, both of * which are absence of evidence rather than evidence of absence: the runner * reported no manifest, or the arm declares only ablations (no manifest names a * tool catalog). Refusing a verdict in either case would punish a consumer for * a capture they were never required to make. */ export declare function checkArmApplication(arm: StrategyArm, manifests: readonly RunManifestLike[]): ArmApplication; //# sourceMappingURL=probe.d.ts.map