/**
 * Derive one (gate, moment) cell — the report's real unit.
 *
 * The pair is the unit rather than the gate because the verdict is genuinely
 * mixed per moment: in this repository `conflict-residue` is bucket A at push
 * and bucket B at pull-request. A gate-shaped row would have to summarise that
 * into a single cell, and every summary of a mixed verdict is a place for a
 * green to hide.
 * @module cli/gate-report-cells
 */
import type { GateRegistryModule, RegistryGate, ResolvedGate } from "./gate-report-registry.js";
import { type HookEvidence } from "./gate-report-executors.js";
import type { Bucket, ExecutorEvidence, Finding, GateMomentCell, MergeBlock, MergeVerdict, ProofMode, TaskProvenance } from "./gate-report-types.js";
/** Everything one moment's cells are derived from. */
export interface MomentContext {
    /** The moment, `:environment` suffix included. */
    readonly moment: string;
    /** `resolveMoment(..., includeOff: true)` keyed by gate id, or null. */
    readonly resolved: ReadonlyMap<string, ResolvedGate> | null;
    /** Why `resolved` is null, when it is. */
    readonly failure: string | null;
}
/** Inputs shared by every cell in the report. */
export interface CellContext {
    readonly registry: GateRegistryModule;
    readonly gates: Record<string, unknown>;
    readonly hooks: HookEvidence;
    /** `package.json` scripts, or null when it could not be read. */
    readonly scripts: Readonly<Record<string, string>> | null;
    /** The runner a command is built with. */
    readonly runner: string;
    /** The workflow name branch-protection contexts are built from. */
    readonly workflowName: string;
    /** Tier 2: the live ruleset's answer for one expected context. */
    readonly blocksMerge: (moment: string, expectedContext: string | null) => Finding<MergeBlock>;
    /** Tier 3: whether the mapped CI job reads the declaration. */
    readonly facade: (gateId: string, qualityJob: string | null) => Finding<boolean>;
    /**
     * Whether this run could read the workflows Tier 3 is written in.
     *
     * When it could, "nothing runs this and nothing declares it" becomes
     * provable rather than merely unproved, and bucket D stops being a thing the
     * report has to decline to say.
     */
    readonly facadeKnown: boolean;
    /** The moment a CI job's verdict actually applies at. */
    readonly mergeMoment: string;
    /** Tier 2 joined with the workflow: does this gate block a merge? */
    readonly merge: (inputs: {
        expectedContext: string | null;
        task: string | null;
        label: string;
    }) => Finding<MergeVerdict>;
}
/**
 * A gate-level `run` override, which applies at every declared moment.
 * @param gates - The gates block
 * @param id - Gate id
 * @returns The task, or null
 */
export declare function gateLevelRun(gates: Record<string, unknown>, id: string): string | null;
/**
 * Which of the five sources supplies this pair's task.
 *
 * Named rather than merely resolved: a per-moment `run` and a gate-level `run`
 * produce identical commands and mean different things, and a registry `taskAt`
 * swap ships to every project while a project `run` does not.
 *
 * This ladder is a SECOND implementation of the one in `resolveMoment`, which
 * returns only the winner's task and cannot say which rung it came from. The
 * duplication is deliberate and its cost is real: a rung added to one and not
 * the other makes this report describe a command the runner will not run. When
 * the fifth rung landed (#2916), a report left un-updated would have printed
 * `security:dast`, `commandExists: false`, and bucket C for a gate that
 * actually runs `security:zap` and passes.
 * @param options - Resolution inputs
 * @param options.entry - The raw per-moment entry
 * @param options.gateRun - A gate-level project `run`
 * @param options.definition - The registry gate
 * @param options.family - The moment's family
 * @param options.scripts - The project's `package.json` scripts, or null when
 *   unreadable. `null` suppresses the `shippedAs` rung entirely: an unknown
 *   manifest cannot establish that the concern-named script is absent.
 * @returns The winning source and its task
 */
export declare function resolveProvenance(options: {
    entry: Record<string, unknown> | null;
    gateRun: string | null;
    definition: RegistryGate | undefined;
    family: string;
    scripts?: Readonly<Record<string, string>> | null;
}): {
    task: string | null;
    provenance: TaskProvenance;
};
/**
 * Whether `package.json` defines the task the pair resolves to.
 * @param scripts - The scripts block, or null when unreadable
 * @param task - The resolved task
 * @returns A three-state finding, never a defaulted pass
 */
export declare function commandExistsFinding(scripts: Readonly<Record<string, string>> | null, task: string | null): Finding<boolean>;
/**
 * Classify one pair into a bucket, or decline to.
 *
 * D is never a fallback. "Nothing runs and nothing is declared" requires
 * proving that no executor exists, and in a consumer the CI half of that proof
 * lives in a file the project does not have — so an unclassifiable pair says
 * so instead of being quietly counted as dark.
 * @param options - Classification inputs
 * @param options.active - Whether the declaration puts the gate into service
 * @param options.mode - How the gate is proved
 * @param options.commandExists - Whether the task exists
 * @param options.executors - Executors proved for this pair
 * @param options.facade - Whether the mapped CI job reads the declaration
 * @param options.atMergeMoment - Whether a CI verdict applies at this moment
 * @param options.facadeKnown - Whether this run could read the CI workflows
 * @returns A bucket, or an explicit refusal
 */
export declare function classifyBucket(options: {
    active: boolean;
    mode: ProofMode | null;
    commandExists: Finding<boolean>;
    executors: readonly ExecutorEvidence[];
    facade: Finding<boolean>;
    atMergeMoment: boolean;
    facadeKnown: boolean;
}): Finding<Bucket>;
/**
 * Build one cell.
 * @param context - Report-wide inputs
 * @param momentContext - Per-moment inputs
 * @param id - Gate id
 * @param qualityJob - The CI job the static table pairs with this gate
 * @returns The cell
 */
export declare function buildCell(context: CellContext, momentContext: MomentContext, id: string, qualityJob: string | null): GateMomentCell;
//# sourceMappingURL=gate-report-cells.d.ts.map