import type { AskClass } from "../ask-origin.js";
import type { HumanReviewGateRow } from "../task-result.js";
import { type OnAsk, type PermissionResult, type ResolvedAsk, type ToolCallRequest } from "../tool-policy.js";
/** One inherited ask grant: a person's clean allow at an ancestor's live approver, on ONE presented shape, to ONE question
 *  (`classes`, the request's class set in `ASK_CLASSES` order) — it answers no stricter question. */
export interface InheritedAskGrant {
    approver: unknown;
    argsJson: string;
    presented: unknown;
    waitMs: number;
    settled?: object;
    classes: readonly AskClass[];
}
/** Does a grant for `granted` cover a question the gate classified as `asked`? `ordinary` — the plain hesitation every other
 *  class is a stricter form of — is covered by any card answered; every other class must have been on the card (the gate reads
 *  facts the station cannot hold, and a class those add was asked of nobody). Unclassified, or a card with no class ⇒ never. */
export declare function askGrantCovers(granted: readonly AskClass[], asked: readonly AskClass[] | undefined): boolean;
/** JSON.stringify throws on a cyclic value (a rewrite object carries no acyclicity guarantee) — `undefined` means "no
 *  comparable shape", which every consumer treats as a mismatch (skip the record / reuse ⇒ re-ask, the safe direction). */
export declare function askGrantShapeOf(args: unknown): string | undefined;
/**
 * Duplicate-frame collapse, the CONSUME half: an inherited layer already resolved THIS call as a clean allow at the
 * SAME approver function, on EXACTLY the byte-shape this ask now presents, for a question that covers this one — asking
 * again is the 2-frame UX debt, not a second authority. Guards, all mismatches re-ask (⇒ `undefined`):
 *  · IDENTITY: the approver FUNCTION reference (never a name), compared through `askApproverIdentity`: a delegated
 *    child's approver is the ancestor's own wrapped with provenance — a different function object, the same operator
 *    (the wrapper grants no authority of its own); identity answers only "same consultation".
 *  · SHAPE: byte-equality against the presented SNAPSHOT; reuse re-emits that snapshot as the executed shape via
 *    `presentedInput` — the same binding as a main-gate approval (shown == executed, by construction).
 *  · CLASS: the gate's stamped `classes` is covered by the set the person answered ({@link askGrantCovers}); a class
 *    the gate's own judges add (a protected target, an out-of-root read) was not on the card. Not covered ⇒ the gate
 *    asks its own question and the grant stays (it answers what it answered; the call-site sweep ends it). The class
 *    set is also the AUTHORITY test (a hook's ask carries `hook`, a fallback `denial_limit_fallback`, a marked tool
 *    `operator_forced`, a protected write `write_protection`, an out-of-root read `probe`, the operator's shell floor
 *    `shell_floor` — a class no inherited station mints from its facts, so no station card answers it; the shell seat's classify-tier
 *    hesitation is `ordinary`, the one question a yes on the same bytes answers) — neither the ask's `decisionReason` nor
 *    its `mandate` word is read.
 *  · LEDGER: the ONE real consultation (timed on the wrapper arm) is booked here — one frame happened, one is booked.
 * The grant lives within one gate evaluation (consumed on reuse, swept at the call site): a REOPENED checkpoint's
 * re-adjudication never sees a stale grant.
 */
export declare function consumeInheritedAskGrant(grants: Map<string, InheritedAskGrant>, onAsk: OnAsk | undefined, humanReviewRef: {
    count: number;
    totalWaitMs: number;
    gates: HumanReviewGateRow[];
}, decision: PermissionResult, req: ToolCallRequest): ResolvedAsk | undefined;
