/** * FU-3 — gate-first auto-validation. Supersedes E015 KL-1. * * The loop, in full (E016 §3.2): * 1. The VALIDATOR designs the gate before any work, read-only: every * explicit requirement maps to one executable check. * 2. The baseline run MUST fail RED. An all-green baseline means the gate * is weak or the work already done — {@link WeakGateError}, loudly. * 3. The gate is visible to the builder but IMMUTABLE during a run. * 4. FAIL output feeds back VERBATIM. * 5. Escalate at the cap (default 3). Gate repair is allowed ONCE per run * when the gate itself is defective; the old gate is preserved in the * run history and the repair does not consume a builder round. * 6. Loud halt at the cap — {@link GateHaltError} carries every run. * * Invariant: the builder never grades its own homework. Checks execute here, * outside every role session; roles only ever see the gate as text. * * Boundary honesty (scope §5): checks are arbitrary shell run with the * operator's privileges — this is validation, not a sandbox. Completion-only * roles cannot change the workspace, so the CLI wires no `applyWork`; the * full repair loop is exercised in tests with a synthetic applier and goes * live with Inc 05's permission-gated write tools. */ import type { Api, Model, StreamFunction } from "@earendil-works/pi-ai"; import type { GateCheck, GateRun } from "./types.js"; /** Parse and validate a validator's gate design (strict; shared by repair). */ export declare function parseGateDesign(raw: string): GateCheck[]; /** FU-3 step 1: the validator designs the gate before any work, read-only. */ export declare function designGate(streamFn: StreamFunction, validatorModel: Model, task: string): Promise; export interface RunGateOptions { cwd: string; timeoutMs?: number; maxOutputChars?: number; } /** * Execute every check; pass = ALL checks exit as expected. Checks run * sequentially (they share one workspace; parallel shells would race). * `exitCode` is the shell's genuine status only: a timeout kills the * process group and records `timedOut` with a null code — 127 therefore * ALWAYS means the shell's own "command not found", which is what the * defective-gate repair keys on. */ export declare function runGate(checks: GateCheck[], purpose: GateRun["purpose"], options: RunGateOptions): Promise; /** Verbatim failing output — FU-3 step 4. No summarising, no paraphrase. */ export declare function verbatimFailures(run: GateRun): string; /** The immutable gate text shown to the builder — FU-3 step 3. */ export declare function gateListing(checks: GateCheck[]): string; export interface GatedFusionOptions { checks: GateCheck[]; cwd: string; maxRounds?: number; /** * Materialise the builder's current output into the workspace. Absent for * completion-only roles: the gate then evaluates once, after the work. */ applyWork?: (builderText: string) => void; /** Produce the next builder output given verbatim gate failures. */ repairWork: (verbatimFailureText: string) => Promise; /** Current builder output before any repair round. */ initialWork: string; /** * Gate repair (FU-3): called at most once per run when a check is * defective (command not found, exit 127). Returns the repaired gate. * The defective run stays in history; the repair consumes NO builder round. * Weakening a legitimate check is forbidden — the repair callback is the * validator, not the builder. */ repairGate?: (defective: GateRun) => Promise; /** * Operator consent, the SAME callback that approved the original design. * The repaired gate is fresh model-authored shell, so it goes through the * identical consent channel before it executes (E001 finding F9 applies to * the repair exactly as to the design). Absent or false = refusal, and the * run halts rather than execute unconsented checks. */ approveGate?: (checks: GateCheck[]) => boolean | Promise; } /** * FU-3 steps 2–6. With no `applyWork`, evaluates the post-work workspace * once (repair is impossible when nothing can change). With `applyWork`, * runs the full repair loop: apply → evaluate → verbatim feedback → repair, * up to `maxRounds`, then halt loudly. */ export declare function runGatedFusion(options: GatedFusionOptions): Promise<{ runs: GateRun[]; finalWork: string; }>; //# sourceMappingURL=gate.d.ts.map