/** The subset of `.lisa.config.json` a gate declaration touches. */
export interface GateConfig {
    readonly gates?: Record<string, unknown>;
}
/** One registry entry, reduced to what deciding a recommendation needs. */
interface RegistryGate {
    readonly task?: string | null;
    readonly taskAt?: Record<string, string>;
}
/** The slice of the shipped registry this module reads. */
export interface GateTaskRegistry {
    readonly REGISTRY: Record<string, RegistryGate | undefined>;
}
/** Whether a gate may be recommended, and why not when it may not. */
export type GateRecommendation = {
    readonly recommend: true;
    readonly task: string | null;
} | {
    readonly recommend: false;
    readonly task: string | null;
    readonly reason: string;
};
/** The result of asking for a gate to be declared. */
export type GateDeclaration = {
    readonly outcome: "declared";
    readonly task: string | null;
} | {
    readonly outcome: "declined";
    readonly task: string | null;
    readonly reason: string;
};
/** What a caller must say to have a gate declared. */
export interface GateDeclarationRequest {
    /** Project root holding `.lisa.config.json` and `package.json`. */
    readonly targetPath: string;
    /** The already-parsed `.lisa.config.json`. */
    readonly config: GateConfig;
    /** Gate id as the shipped registry spells it. */
    readonly gateId: string;
    /** The moment the gate would be declared at. */
    readonly moment: string;
    /** The level it would be declared at. */
    readonly level: string;
    /** Registry loader; injected by tests, never in production. */
    readonly loadRegistry?: () => Promise<GateTaskRegistry | null>;
}
/**
 * Add one gate to a config without touching anything else.
 *
 * A gate is declared per MOMENT, and doctor declares one moment per call — so
 * the per-gate object is merged into, never replaced. Replacing it drops a
 * moment the project already declared while leaving the gate id in place, so
 * the config still reads as configured and the moment that stopped running is
 * invisible until something ships past it. The same goes for the gate-level
 * `run` override, a sibling of the moment keys rather than a moment: losing it
 * silently reverts the gate to its registry default task, which is a different
 * check than the project asked for.
 *
 * Returns a new object rather than mutating, so a caller that decides not to
 * write still holds the original.
 * @param config - Parsed `.lisa.config.json`
 * @param gateId - Gate id to declare
 * @param moment - Moment to declare it at
 * @param level - Level to declare it at
 * @returns A copy declaring the gate
 */
export declare function withGate<T extends GateConfig>(config: T, gateId: string, moment: string, level: string): T;
/**
 * The task a gate resolves to at one moment, per the shipped registry.
 *
 * A gate may name a different prover per moment — traceability proves the
 * pull-request moment with `validate-pr` and the push moment with
 * `validate-push` — so the moment is part of the question, not a detail.
 * @param gate - The registry entry
 * @param moment - The moment being declared
 * @returns The task name, or null when the registry names none
 */
export declare function taskForMoment(gate: RegistryGate, moment: string): string | null;
/**
 * Decide whether doctor may recommend a gate.
 *
 * Every decline is a decline: when Lisa cannot READ the registry it does not
 * assume the gate is fine. An unverifiable recommendation and a
 * known-bad recommendation cost a consumer the same red build.
 * @param request - The gate, moment, level, and project being considered
 * @returns Whether the gate may be recommended, and why not when it may not
 */
export declare function canRecommendGate(request: GateDeclarationRequest): Promise<GateRecommendation>;
/**
 * Declare a gate in `.lisa.config.json` — but only when its task resolves.
 *
 * The verification and the write are one call on purpose. See the module note:
 * a guard that a caller must remember to invoke is a guard that a future caller
 * forgets.
 * @param request - The gate, moment, level, and project being declared
 * @returns Whether the declaration was written, and why not when it was not
 */
export declare function declareGate(request: GateDeclarationRequest): Promise<GateDeclaration>;
export {};
//# sourceMappingURL=doctor-gate-recommendation.d.ts.map