/**
 * Ask classifier + stall suppression (RUSH-1477).
 *
 * ~39% of AskUserQuestion calls are workflow-stalls ("should I…?", "what's next?",
 * "merge now?"). The feed's first job is to make those disappear so real Decisions
 * and Approvals stay visible.
 *
 * Pipeline:
 *   1. Classify every block into Decision / Approval / Clarification / Stall / Fyi
 *   2. Suppress stalls (and pure FYIs) with an auto-answer so they never render
 *   3. Surface Decision + Approval (+ Clarification when it needs a real fact)
 *
 * Rules-based on stable high-volume shapes. Pure classify/match; suppression has
 * side effects via the feed store when applied.
 */
import type { OpenBlock } from './feed/feed.js';
/** Taxonomy for a published ask. Exactly one class per block. */
export type AskClass = 'decision' | 'approval' | 'clarification' | 'stall' | 'fyi';
export interface Classification {
    class: AskClass;
    /** Why this class was chosen (rule name). */
    rule: string;
    /** True when the feed should hide this block and auto-answer it. */
    suppress: boolean;
    /** Auto-answer text when suppress is true. */
    autoAnswer?: string;
}
/** Scan text used for classification. */
export declare function askScanText(block: Pick<OpenBlock, 'questions'>): string;
/**
 * Classify one ask from free text (+ optional explicit blockClass from the agent).
 * Explicit blockClass from the agent is honored as a floor: 'decision' never becomes
 * a suppressible stall (false-suppress rate ~0 for real Decisions).
 */
export declare function classifyAsk(text: string, opts?: {
    header?: string;
    blockClass?: OpenBlock['blockClass'];
}): Classification;
/** Classify a full open block (all questions concatenated). */
export declare function classifyBlock(block: OpenBlock): Classification;
export interface SuppressResult {
    blockId: string;
    class: AskClass;
    rule: string;
    autoAnswer: string;
    /** True when the block was removed from the visible feed. */
    suppressed: boolean;
}
/**
 * Auto-answer + remove a suppressible block so it never renders as a card.
 * Logs the stall as answered by policy:stall-suppression.
 */
export declare function suppressStallBlock(block: OpenBlock, root?: string, mailboxRoot?: string): SuppressResult;
export interface FeedFilterResult {
    /** Blocks that should render as cards. */
    surfaced: OpenBlock[];
    /** Suppression audit rows (stalls auto-resolved). */
    suppressed: SuppressResult[];
    /** Per-class counts over the input set (before suppression). */
    counts: Record<AskClass, number>;
}
/**
 * Classify every block; optionally apply stall suppression (mutate store).
 * When `apply` is false, only classifies (dry run for --json audit).
 */
export declare function filterBlocksForFeed(blocks: OpenBlock[], opts?: {
    apply?: boolean;
    root?: string;
    mailboxRoot?: string;
}): FeedFilterResult;
/** Human digest: "31 stalls auto-resolved by policy". */
export declare function suppressionDigest(result: FeedFilterResult): string;
