import type { ParsedWorkflow, ParsedWorkflowJob, ParsedWorkflowStep } from "./doctor-readiness-workflows.js";
/** One command an automated job runs, with the file coordinates to cite it. */
export interface ScannedCommand {
    readonly workflow: string;
    readonly jobId: string;
    readonly command: string;
}
/** What one scan of a repository's workflows established. */
export interface OperationScan {
    /** Commands running in a job this file proves is automated and ungated. */
    readonly ungated: readonly ScannedCommand[];
    /** Commands running in a job something already gates. */
    readonly gated: readonly ScannedCommand[];
    /** Stated reasons a job's gating could not be settled offline. */
    readonly unresolved: readonly string[];
}
/** Optional refinements a caller layers onto a scan. */
export interface ScanOptions {
    /**
     * A step-level exemption, evaluated after a matching step is found. B1 uses it
     * for a destructive command that has a preceding backup in the same job; a
     * backup that runs later is not a way back for the already-executed command.
     */
    readonly exemptStep?: (job: ParsedWorkflowJob, step: ParsedWorkflowStep) => boolean;
    /**
     * A workflow-level reason the match cannot be settled offline, returning
     * `null` when it can. Used for triggers that make the operation obviously
     * ephemeral — a per-pull-request teardown destroys what that same pull
     * request created, so there is nothing durable for a gate to protect.
     */
    readonly unresolvedWorkflow?: (workflow: ParsedWorkflow) => string | null;
    /**
     * A job-level reason the match cannot be settled offline, returning `null`
     * when it can. Used for a job that boots its own `services:` containers.
     */
    readonly unresolvedJob?: (job: ParsedWorkflowJob) => string | null;
    /**
     * A step-level reason the match cannot be settled offline, returning `null`
     * when it can. Used when the same job-level evidence only applies to some
     * matching commands.
     */
    readonly unresolvedStep?: (workflow: ParsedWorkflow, job: ParsedWorkflowJob, step: ParsedWorkflowStep) => string | null;
    /**
     * A job-level reusable workflow call reason the scan cannot settle offline,
     * returning `null` when the call carries no relevant evidence.
     */
    readonly unresolvedJobCall?: (workflow: ParsedWorkflow, job: ParsedWorkflowJob) => string | null;
    /**
     * An action step reason the scan cannot settle offline, returning `null` when
     * the action carries no relevant evidence.
     */
    readonly unresolvedActionStep?: (workflow: ParsedWorkflow, job: ParsedWorkflowJob, step: ParsedWorkflowStep) => string | null;
}
/**
 * Whether any text — a command, a job's `env:` block, or the two together —
 * names an obviously ephemeral target.
 * @param text - The text to screen (case is normalized here)
 * @returns True when the text names throwaway state
 */
export declare function looksEphemeral(text: string): boolean;
/**
 * Whether the command plausibly targets one of the job's own `services:`
 * containers. A service only defers the step it can explain; an unrelated
 * container in the same job must not hide a durable target.
 * @param job - The job to consider
 * @param step - The step being classified
 * @returns True when the command plausibly points at a job-local service
 */
export declare function commandTargetsOwnedService(job: ParsedWorkflowJob, step: ParsedWorkflowStep): boolean;
/**
 * Whether one command is the kind of operation a producer is looking for. The
 * job travels with the command because the evidence that settles the question
 * is often outside the command text — a job `env:` block naming a CI database,
 * for instance.
 */
export type CommandPredicate = (command: string, job: ParsedWorkflowJob, step: ParsedWorkflowStep) => boolean;
/**
 * Whether a workflow's declared triggers prove it runs without a human. A
 * workflow that declares no `on:` block this parser could read is treated as
 * NOT automated, because absence of a readable trigger is absence of proof.
 * @param workflow - The parsed workflow
 * @returns True when at least one trigger fires with no human in the loop
 */
export declare function runsUnattended(workflow: ParsedWorkflow): boolean;
/**
 * Whether anything in the file already gates this job. A declared
 * `environment:` counts even though its protection rules are unreadable
 * offline: the operator has named a deployment boundary, and calling that
 * ungated would be exactly the false positive this module exists to prevent.
 * @param job - The parsed job
 * @returns True when the job is conditional or names an environment
 */
export declare function jobIsGated(job: ParsedWorkflowJob): boolean;
/**
 * Whether a step is individually gated — a conditional step, or a command that
 * names its own confirmation or rehearsal switch.
 * @param step - The parsed step
 * @returns True when the step carries its own guard
 */
export declare function stepIsGated(step: ParsedWorkflowStep): boolean;
/**
 * Scan every workflow for the commands matching a predicate, partitioned by
 * whether the file itself proves the command runs unattended and ungated.
 * @param workflows - Parsed workflows
 * @param matches - Predicate over a lower-cased `run` command
 * @param options - Scan refinements
 * @returns The partitioned scan
 */
export declare function scanCommands(workflows: readonly ParsedWorkflow[], matches: CommandPredicate, options?: ScanOptions): OperationScan;
/**
 * Whether the repository checks in an automation runbook — the "way back" half
 * of B1 and B4. The `automation-runbook-contract` rule puts them under
 * `.lisa/automations/*.runbook.md`; the conventional documentation homes are
 * honored as well, so a project that writes its recovery procedure somewhere
 * reasonable is never told it has none.
 * @param root - Repository root
 * @returns True when at least one runbook is checked in
 */
export declare function hasCheckedInRunbook(root: string): Promise<boolean>;
/**
 * Render scanned commands as one evidence string, quoting the file, the job, and
 * the command so the operator can go straight to the line.
 * @param commands - The commands to cite
 * @param limit - Most commands to quote before summarizing the remainder
 * @returns One evidence string
 */
export declare function describeCommands(commands: readonly ScannedCommand[], limit: number): string;
//# sourceMappingURL=doctor-readiness-operations.d.ts.map