/**
 * L2 mechanical verification gate (design/54) — the "verifiable outputs" exit oracle.
 *
 * Runs a TRUSTED, spec-derived suite of commands (build / type-check / test) in an {@link ExecutionEnv}
 * and gates on the **real exit codes**: pass = every step exited 0. This is the mechanical half of
 * verifiable outputs (design/54 §2); the de-correlated LLM-judge half is {@link runWithVerification}
 * (L3). It catches what tests cover; service[33] measured L2 alone misses 50-100% of semantic/edge
 * defects, which is why L3 runs on what passes L2.
 *
 * **It is a thin exit oracle, not a framework** — no model, no Runner, no agents dependency. It just runs
 * commands and reports their exit truthfully, choosing the streaming `execStream` on a remote env (long
 * builds, read-timeout, output cap) or the buffered `exec` on a base env. Which commands to run, and how
 * to compose L2 with L3 / per-module sub-gates, is the caller's (profile's) job (design/54 §4).
 *
 * 🔴 SECURITY (design/53 §2.B, threat BUG8 — "L2 can be gamed"): `steps` MUST be a trusted, spec-derived
 * suite — NOT test files an **untrusted worker** authored (a worker can write `assert(true)` / happy-path
 * tests that pass while the code is broken, pushing all pressure onto an uncalibrated L3). This helper does
 * not and cannot know which commands are trustworthy; the caller owns that. The gate's guarantee is narrow:
 * "did these exact commands all exit 0 in this env" — nothing about whether the commands are meaningful,
 * whether the env is isolated (design/53 §E = deployment), or the semantics of the change (that is L3).
 */
import type { ExecutionEnv } from "../internal/harness-types.js";
/** One command in an L2 suite. */
export interface ExecStep {
    /** Shell command to run (e.g. `"npm test"`, `"tsc --noEmit"`, `"git diff"`). */
    command: string;
    /** Human label for reporting. Default: the command string. */
    label?: string;
    /** Working directory; relative paths resolve against the env root. Default: the env's cwd. */
    cwd?: string;
    /** Extra environment variables for this command. */
    env?: Record<string, string>;
    /** Per-step timeout (seconds). Default: none. */
    timeoutSec?: number;
}
/** The outcome of a single {@link ExecStep}. */
export interface ExecStepResult {
    label: string;
    command: string;
    /** The real exit code, or `null` when the command never produced one (transport error / timeout / abort). */
    exitCode: number | null;
    stdout: string;
    stderr: string;
    /** `exitCode === 0`. A `null` exit is **never** `ok` (we can't confirm success, so we don't pass it). */
    ok: boolean;
    /** Set when the step failed to RUN (an `ExecutionError`/`RemoteExecutionError` code) — distinct from a non-zero exit. */
    errorCode?: string;
    /** True when captured output was truncated at {@link ExecGateOptions.maxOutputBytes}. */
    truncated?: boolean;
}
/** The L2 verdict over a whole suite. */
export interface ExecGateResult {
    /** True iff there was ≥1 step AND every step ran and exited 0. An EMPTY suite is `false` (nothing was verified — not a vacuous pass). */
    passed: boolean;
    /** Per-step detail, in order. With `stopOnFailure` (default), steps after the first failure are absent. */
    steps: ExecStepResult[];
}
/** Options for {@link runExecGate}. */
export interface ExecGateOptions {
    /** Stop at the first failed/non-zero step (default `true` — a cheap CI-style short-circuit). */
    stopOnFailure?: boolean;
    /** Cap captured output **per step** in UTF-8 bytes (default 64 KiB) so a `find /` can't flood memory. */
    maxOutputBytes?: number;
    /** Idle read timeout (ms) for the streaming (remote) path; ignored on the buffered path. */
    readTimeoutMs?: number;
    /** Abort the whole gate (also forwarded to each command). */
    signal?: AbortSignal;
}
/**
 * Run an L2 mechanical gate: execute `steps` in `env` and gate on real exit codes. See the file header for
 * the security contract — `steps` must be a trusted, spec-derived suite, not worker-authored tests.
 */
export declare function runExecGate(env: ExecutionEnv, steps: ExecStep[], options?: ExecGateOptions): Promise<ExecGateResult>;
