/** * distill-oracle.ts — Tiered `resolved` oracle for distill / weight-EFT SFT data. * * THE PROBLEM: weight-EFT's SFT data wants a gold `resolved: boolean` per * trajectory. Ruflo has no SWE-bench oracle, so today `resolved` is * structural-confidence — a proxy that risks distilling plausible-but-wrong * completions. This module replaces that single proxy with a TIERED labeler, * where every label carries HONEST PROVENANCE (ADR-169 reporting integrity — a * proxy is never presented as ground truth). * * ── TIERS (tried in order, per trajectory) ────────────────────────────────── * TIER 1 — MECHANICAL ORACLE (provenance `oracle:test-exec`, real ground truth) * When a trajectory carries a test spec (SWE-bench FAIL_TO_PASS shape) or * maps to a metaharness/darwin bench-suite case, EXECUTE the real eval and * set resolved = tests-pass. This needs Docker/compute, so it runs on a * REMOTE host over SSH (host parameterized via `remote` / env * RUFLO_DISTILL_REMOTE — never hard-coded). DRY-RUN by default: it prints * the ssh/darwin-bench/eval commands + a preflight plan and does NOT touch * the network; only `execute: true` runs the real eval (with a wrapped, * non-fatal preflight probe first). * * TIER 2 — FABLE JUDGE (provenance `judge:fable`, smarter proxy) * For trajectories with no mechanical spec, judge via the cost-disciplined * headless Fable harness (fable-harness.ts). Opt-in and OFF by default; * spends nothing unless `fableJudge: true` AND a `maxBudgetUsd` cap is set. * * TIER 3 — STRUCTURAL PROXY (provenance `proxy:structural`, weakest) * The existing output-verifier structural confidence. Always available, * $0, no external calls. Explicitly the weakest signal, clearly labeled. * * DEFAULT (no opts): dry-run oracle preflight + structural-proxy fallback. * ZERO spend, no SSH exec, no Fable call. Everything degrades gracefully * (ADR-150) — a missing remote or a failed probe is reported, never fatal. * * @module services/distill-oracle */ import { type VerifyTaskKind } from '../ruvector/output-verifier.js'; import { FableHarness, type ReflectItem, type ReflectResult } from './fable-harness.js'; export declare const MH_DARWIN_PIN = "0.9.0"; export type ResolvedProvenance = 'oracle:test-exec' | 'judge:fable' | 'proxy:structural'; /** SWE-bench-shaped / bench-suite-mapped test spec that Tier 1 can execute. */ export interface TestSpec { /** SWE-bench FAIL_TO_PASS tests — must go red→green for `resolved`. */ failToPass?: string[]; /** SWE-bench PASS_TO_PASS tests — must stay green (no regressions). */ passToPass?: string[]; /** Repo identifier (for the remote checkout). */ repo?: string; /** Base commit the patch applies onto. */ baseCommit?: string; /** Candidate patch/diff to apply before evaluating. */ patch?: string; /** An explicit eval command that returns 0 iff the task is resolved. */ evalCommand?: string; /** metaharness/darwin bench-suite this case belongs to. */ benchSuite?: string; /** Case id within the bench suite. */ benchCase?: string; /** Working directory on the remote host (default derived). */ workdir?: string; } /** * Minimal trajectory contract. Extra fields are preserved verbatim on output * (the labeler spreads `...trajectory`). `task`/`output` feed the fable judge * and structural proxy; `testSpec` (when present) unlocks Tier 1. */ export interface Trajectory { id: string; task?: string; output?: string; testSpec?: TestSpec; /** Hint for the structural verifier's task-kind detection. */ taskKind?: VerifyTaskKind; [key: string]: unknown; } export interface LabelOptions { /** SSH host for Tier-1 execution. Falls back to env RUFLO_DISTILL_REMOTE. Never hard-coded. */ remote?: string; /** Run the REAL Tier-1 eval over SSH. Default false → dry-run preflight only. */ execute?: boolean; /** Enable the Tier-2 Fable judge. Default false. Requires maxBudgetUsd to spend. */ fableJudge?: boolean; /** Hard budget cap (USD) for the Fable tier. No cap ⇒ no Fable spend. */ maxBudgetUsd?: number; /** Items per Fable call (default 20 — see FABLE_COST_MODEL). */ fableBatchSize?: number; /** Structural verifier: min score to call a trajectory resolved (default: strict — confident only). */ minStructuralConfidence?: number; /** Injected Tier-1 runner (tests). Defaults to a real SSH command runner. */ runner?: OracleRunner; /** Injected Tier-2 harness (tests). Defaults to a real FableHarness. */ harness?: FableHarness; } /** A trajectory with its resolved label + honest provenance. */ export type LabeledTrajectory = T & { resolved: boolean; resolvedBy: ResolvedProvenance; resolvedConfidence?: number; resolvedReason?: string; /** Present for trajectories that had a mechanical spec — the Tier-1 plan/outcome. */ oraclePreflight?: OraclePreflight; }; export type OracleKind = 'ssh-darwin-bench' | 'ssh-swebench-eval' | 'ssh-eval' | 'local-eval'; /** The concrete command plan for executing a trajectory's eval on the remote. */ export interface OraclePlan { kind: OracleKind; /** Resolved remote host, or null when none is configured. */ remote: string | null; /** Preflight probe commands (reachability, docker/darwin presence). */ probeCommands: string[]; /** The eval commands whose success ⇒ resolved. */ evalCommands: string[]; /** Human note describing how the resolved boolean is derived. */ parseHint: string; } /** Preflight/dry-run record attached to labeled trajectories that had a spec. */ export interface OraclePreflight { /** True when nothing was executed (default path). */ dryRun: boolean; plan: OraclePlan; /** Probe outcome when executed (execute:true); absent in dry-run. */ probe?: { ok: boolean; reason: string; }; /** Why Tier 1 did not produce the final label (e.g. dry-run, no remote, probe failed). */ fellThroughBecause?: string; } /** Outcome of a real Tier-1 eval. */ export interface OracleOutcome { resolved: boolean; reason: string; } /** Result of a shelled command. */ export interface CommandResult { stdout: string; stderr: string; code: number | null; } /** Injectable command executor (tests mock this instead of touching SSH). */ export type CommandExec = (cmd: string, args: string[], opts: { timeoutMs: number; }) => Promise; /** Tier-1 runner contract: probe the remote, then run the eval. */ export interface OracleRunner { preflight(plan: OraclePlan): Promise<{ ok: boolean; reason: string; }>; runEval(plan: OraclePlan, spec: TestSpec): Promise; } /** * Label each trajectory with `resolved` + honest provenance, trying the tiers * in order per trajectory. See the module header for tier semantics and the * zero-spend default guarantee. */ export declare function labelResolved(trajectories: T[], opts?: LabelOptions): Promise>>; /** * Reflective failure analysis (GEPA/evolve mutation input). Thin, cost- * disciplined pass-through to the Fable harness. Opt-in: returns [] unless a * harness with a budget cap is provided/configured. */ export declare function reflectFailures(items: ReflectItem[], opts?: { maxBudgetUsd?: number; fableBatchSize?: number; harness?: FableHarness; }): Promise; /** A trajectory can be mechanically evaluated iff it carries an actionable spec. */ export declare function hasMechanicalSpec(t: Trajectory): boolean; /** Resolve the remote host from opts → env, never a hard-coded host. */ export declare function resolveRemote(remote?: string): string | null; /** * Build the concrete command plan for a spec. Pure — constructs command strings * only; executes nothing. `remote` is always substituted from the parameter, * never hard-coded. */ export declare function buildOraclePlan(spec: TestSpec, remote: string | null): OraclePlan; /** * Default command executor: shells out, piping any heredoc/stdin via argv only * (commands are self-contained strings run through `sh -c`). Never invoked on * the default (dry-run) path. */ export declare const defaultCommandExec: CommandExec; /** * Build a real SSH-backed oracle runner. `exec` is injectable so tests assert * command construction without ever touching a network. Each plan command is * run via `sh -c ` so the fully-rendered ssh line executes as-is. */ export declare function createSshOracleRunner(exec?: CommandExec, timeoutMs?: number): OracleRunner; export default labelResolved; //# sourceMappingURL=distill-oracle.d.ts.map