/**
 * The ONE exit for an auto-mode classification that did not RULE ({@link rungDidNotRule}: the classifier leg failed or its
 * budget ran out — `error` / `timeout` — or it replied with no verdict at all — `parse_error`) — shared by both classifier
 * stations, the leg's gate and an ancestor's frozen classifier in the policy fold, so the rule is written once.
 *
 * ONE fork, on the APPROVAL ROUTE the station states (`ApprovalRoute`, the one seat decision — `live_approver`,
 * `durable_park` or `none`): with a person on the route, the ask goes on carrying why (`classifierNoRuling`, its text saying it too), and a person decides — never
 * counted (a person's refusal of it is a person's); without one, an unavailable classification is refused with CC's `x1t`
 * sentence (its FORM, `unavailable`, attested on the deny) and is never counted, while a reply with no verdict goes back to
 * the station's ruling path (`counted`): refused with its own sentence and counted on the denial limit, so the bound falls
 * back to a person (CC: `Cr` excludes unavailable; failureMode is counted). The handed-on ask carries `requiresRealApproval`:
 * no automatic lane may answer it in the classifier's stead — not a blanket `onAsk:"allow"`, not the sandbox admission, not a
 * budget resolver over its park. Asking where a person can be asked is a declared departure (CC refuses).
 *
 * The observer hears every such classification with where the call went, except while the call is being aborted — a halt,
 * or the run's end. It is observe-only: a throw never changes the arm.
 */
import { type AutoModeClassifierRound, type AutoModeDenialTracker, type AutoModeFallbackCause, type UnarmedDenialLimitFallback } from "./auto-mode.js";
import { type PermissionResult, type ResolvedAsk, type ToolCallRequest } from "./tool-policy.js";
import type { Settlement } from "./gate-outcome.js";
import type { ApprovalRoute } from "./wiring-manifest.js";
/** Where a classification that did not rule sent the call: `asked` = on to the approval seat, `denied` = refused — the
 *  projection of the route ({@link classifierUnavailableDispositionOf}), never a second reading of it. */
export type ClassifierUnavailableDisposition = "asked" | "denied";
/** The disposition a route projects: a route with a person on it is `asked`, `none` is `denied`. */
export declare function classifierUnavailableDispositionOf(route: ApprovalRoute): ClassifierUnavailableDisposition;
/** What the stations' observer receives — the facts the `classifier.unavailable` notice is composed from. `cause` is why
 *  the classification did not rule ({@link AutoModeFallbackCause}: `error` / `timeout`, or `parse_error` for a reply with no
 *  verdict); `route` is where the station sent the call (the disposition the notice's detail carries is its projection). */
export interface ClassifierUnavailableInfo {
    toolName: string;
    toolCallId: string;
    cause: AutoModeFallbackCause;
    route: ApprovalRoute;
}
export type ClassifierUnavailableObserver = (info: ClassifierUnavailableInfo) => void;
/** The station's two facts for the fork: the route an ask it hands on takes (`approvalRouteOf` / `frozenApproverRoute` —
 *  a value outside the two person routes, or none stated, is `none`), and who hears it. */
export interface ClassifierUnavailableSeat {
    route?: ApprovalRoute;
    onUnavailable?: ClassifierUnavailableObserver;
}
/** The arm the fork chose: the ask to hand on, the refusal, or — a reply with no verdict and no seat — the station's own
 *  counted ruling path. */
export type ClassifierNoRulingArm<A> = {
    kind: "asked";
    ask: A;
} | {
    kind: "denied";
    deny: PermissionResult;
} | {
    kind: "counted";
};
export declare function classifierNoRulingArm<A extends Extract<PermissionResult, {
    action: "ask";
}>>(args: {
    ask: A;
    req: ToolCallRequest;
    cause: AutoModeFallbackCause;
    /** The ladder's attribution, for the refusal's sentence (it names both rungs when the ladder moved). */
    attribution?: AutoModeClassifierRound;
    seat: ClassifierUnavailableSeat | undefined;
    /** The call is being aborted (its per-call signal — a halt, or the run's end): the observer is not told (the arm is chosen
     *  as ever). */
    aborted: boolean;
}): ClassifierNoRulingArm<A>;
/**
 * The no-ruling card's settlement (both stations): a card THIS station's no-ruling arm handed on for this call (`mintedHere` —
 * a policy's own `classifierNoRuling`, or a card another station minted, is not this station's classification and counts
 * nothing here) that the seat's deployment POLICY refused (settlement `policy_refused` — a machine settled it, not a person)
 * counts on the denial limit like a ruling refusal, because "handed to a person" means a person settled it. Returns the fallback the count minted when it reached the
 * bound — the station then puts the same call to the same seat as the denial-limit fallback, and a deny nobody judged there
 * stops the run through the existing headless arm. A person's answer (allow or refusal), a fallback card, and every other
 * settlement count nothing.
 */
export declare function settleNoRulingAsk(opts: {
    ask: PermissionResult;
    mintedHere: boolean;
    resolved: {
        action: ResolvedAsk["action"];
        settlement?: Settlement;
    };
    tracker: AutoModeDenialTracker | undefined;
}): UnarmedDenialLimitFallback | undefined;
