import { type ToolCallRequest } from "./tool-policy.js";
import { type AllowRuleMember, type AllowRuleShadow } from "./allow-rule-shadow.js";
import { type PersistedRule } from "./permission-rule-model.js";
import { type AskClass, type AssertAllKeysHandled, type PermissionMode, type PersistedRuleMandate } from "./ask-origin.js";
import { type EngineNotice } from "./engine-notice.js";
/** Why an entry grants (or refuses) nothing — the closed set the start-of-run notice names, for every list. */
export declare const ALLOW_ENTRY_INERT_REASONS: readonly ["wildcard_all", "namespace_wildcard", "path_pattern", "domain", "content_unsupported", "grammar"];
export type AllowEntryInertReason = (typeof ALLOW_ENTRY_INERT_REASONS)[number];
/** One entry the grammar reads (kind closed): a whole non-shell tool; a protocol namespace; the whole shell tool; a shell
 *  command rule; the Read directory form; a deny-side path pattern (a skill's `disallowed-tools`). */
export type CompiledAllowEntry = {
    readonly kind: "tool";
    readonly name: string;
} | {
    readonly kind: "namespace";
    readonly pattern: string;
} | {
    readonly kind: "shell";
    readonly name: string;
} | {
    readonly kind: "command";
    readonly rule: PersistedRule;
} | {
    readonly kind: "read_dir";
    readonly rule: PersistedRule;
} | {
    readonly kind: "path";
    readonly rule: PersistedRule;
};
/** Read one entry under one direction. */
export declare function compileAllowEntry(raw: string, behavior: "allow" | "deny"): CompiledAllowEntry | AllowEntryInertReason;
/**
 * Compile one list WHOLE: the entries it reads and the ones it reads as nothing. An allow list holding `*` voids the list
 * (every other entry on it reads as nothing too: the list grants nothing — the safe direction). A `*` on a deny list reads
 * as nothing by itself and the rest of that list still refuses: a deny list never loses an entry to a wildcard beside it.
 */
export declare function compileAllowList(entries: readonly string[], behavior: "allow" | "deny"): {
    rows: Array<{
        entry: string;
        compiled: CompiledAllowEntry;
    }>;
    inert: Array<{
        entry: string;
        reason: AllowEntryInertReason;
    }>;
};
/** The programs whose open allow rule the reference implementation drops in auto mode — its interpreter / launcher table
 *  plus the shells and the run-anything builtins (2.1.280). A program that only reaches the network is not here. */
export declare const AUTO_STRIPPED_PROGRAMS: readonly ["python", "python3", "python2", "node", "deno", "tsx", "ruby", "perl", "php", "lua", "npx", "bunx", "npm run", "yarn run", "pnpm run", "bun run", "bash", "sh", "ssh", "zsh", "fish", "eval", "exec", "env", "xargs", "sudo"];
/**
 * Does auto mode strip this allow entry for this call (see the module doc)? Read for every rule-shaped member — a list
 * entry, and a person's stored row through {@link autoStrippedRule}; a hook's allow is not an entry and is never stripped.
 * A stripped entry takes no part in the match (the reference removes it before matching), so it neither clears nor is
 * disclosed.
 */
export declare function autoStripped(compiled: CompiledAllowEntry, call: ToolCallRequest | undefined): boolean;
/** {@link autoStripped} over a person's stored ALLOW row (a deny / ask row is never stripped; a path row never is). */
export declare function autoStrippedRule(rule: PersistedRule, call: ToolCallRequest): boolean;
/** One row a list matcher reads. */
export interface AllowEntryRow {
    readonly behavior: "allow" | "deny";
    readonly entry: string;
    readonly compiled: CompiledAllowEntry;
}
/** The call facts a content row is judged against — the persisted lane's own bases. */
export interface AllowEntryJudgeContext {
    readonly root: string | undefined;
    readonly sessionId: string | undefined;
    readonly liveCwd: () => string | undefined;
    readonly home: string | undefined;
}
/**
 * The ONE list matcher, both directions — the rows that speak for the call, or undefined. ALLOW: the first name row that
 * reaches the call, else the command rows' coverage (the persisted allow matcher — the whole command, or each segment
 * covered by a row or read-only by itself), else the Read directory rows. DENY: a name row, a command row whose program run
 * the call performs (the wide tightening reading; a call that cannot be read against the row is refused too), or a path row
 * the call's target reaches.
 */
export declare function judgeAllowEntries<R extends AllowEntryRow>(rows: readonly R[], req: ToolCallRequest, behavior: "allow" | "deny", ctx: AllowEntryJudgeContext): readonly R[] | undefined;
/** The allow rows of a list, as the allow layer reads them in `mode`: the strip applied BEFORE the match (in `auto`). */
export declare function allowingRows<R extends AllowEntryRow>(rows: readonly R[], req: ToolCallRequest, mode: PermissionMode | undefined): readonly R[];
/** The two sources {@link AllowEntryTable} holds (a skill's list is the skill table's). */
export type AllowEntrySource = "request" | "deployment";
/** What spoke for a call: the entries it stands on, as the list spells them. */
export interface AllowEntryHit {
    readonly entries: readonly string[];
}
/** The face the gate reads one entry list through. */
export interface AllowEntryLane {
    /** The allow layer's member: what grants this call in this mode, or undefined. */
    allowing(req: ToolCallRequest, mode: PermissionMode | undefined): AllowEntryHit | undefined;
}
/** The gate inputs the two entry lists ride (a member group of `ToolGateInput`). Each is the allow layer's member for its
 *  source — read under the one consumption predicate beside a person's stored rows and a skill's list, clearing only what an
 *  allow rule may clear — with its attribution sink (`onAllowed` observes a call it cleared; never affects the outcome).
 *  Absent ⇒ that source has no rows. */
export interface AllowEntryGateSeats {
    deploymentAllows?: AllowEntryLane & {
        onAllowed?: (info: {
            toolName: string;
            toolCallId: string;
            entries: readonly string[];
        }) => void;
    };
    requestAllows?: AllowEntryLane & {
        onAllowed?: (info: {
            toolName: string;
            toolCallId: string;
            entries: readonly string[];
        }) => void;
    };
}
/**
 * One source's allow rows, compiled once: the request's (prepare seeds it from the spec's snapshot and, in a delegated
 * child, from the parent's capture) or the deployment's (compiled from the Runner's snapshot). Allow rows only — neither
 * list has a deny side. Identity is the contract: prepare seeds it, the delegation capture and the gate's lane read it.
 */
export declare class AllowEntryTable {
    private held;
    /** Write a list's rows (a row already held is not held twice). Returns the entries that read as nothing. */
    seed(entries: readonly string[]): ReadonlyArray<{
        entry: string;
        reason: AllowEntryInertReason;
    }>;
    /** The entries held, as written (a copy) — what a delegated child is handed. */
    entries(): readonly string[];
    /** The lane over this table, bound to the leg's call facts. */
    lane(ctx: AllowEntryJudgeContext): AllowEntryLane;
}
/**
 * Seed one leg's request and deployment tables — a delegated child's captured request entries first (an entry that reads as
 * nothing was announced where it was written), then the leg's own list; the deployment's (announced once, at construction) —
 * and return the dead entries of the leg's OWN lists, the skills' beside the request's, for its one start-of-run notice.
 */
export declare function seedAllowEntryTables(tables: {
    readonly request: AllowEntryTable;
    readonly deployment: AllowEntryTable;
}, lists: {
    skillInert: ReadonlyArray<{
        skill: string;
        list: "allowed-tools" | "disallowed-tools";
        entry: string;
        reason: AllowEntryInertReason;
    }>;
    inherited: readonly string[] | undefined;
    request: readonly string[] | undefined;
    deployment: readonly string[] | undefined;
}): AllowEntryInertNote[];
/** The deployment's allow rules, read ONCE at construction: screened (a value that is not a list of strings refuses), frozen,
 *  and its dead entries announced once (no session). Returns the deps with the snapshot in place of the caller's list. */
export declare function withDeploymentAllowedTools<D extends {
    readonly allowedTools?: readonly string[];
    readonly onNotice?: ((n: EngineNotice) => void) | undefined;
}>(deps: D): D;
/** The code a list value that is not a list of strings refuses with — the policy compiler's family, with its issues. */
export declare const INVALID_PERMISSION_RULES_CODE = "config.invalid_permission_rules";
/**
 * Screen and snapshot one `allowedTools` value (`seat` names the key in the refusal): absent ⇒ undefined; a list of strings
 * ⇒ a frozen copy (the one read every later reader takes); anything else refuses loudly with
 * {@link INVALID_PERMISSION_RULES_CODE} and an issue per defect — never dropped, never read as "no entries".
 */
export declare function screenAllowedToolsValue(value: unknown, seat: string): readonly string[] | undefined;
/** The disclosure record for one member, minted from the entries it matched: each sanitized (deployment or model-authored
 *  text on a human trust boundary) and capped, the rest counted. */
export declare function allowRuleShadowOf(member: AllowRuleMember, entries: readonly string[]): AllowRuleShadow;
/** Read a disclosure value off a decision WITHOUT trusting it (a policy's own value, an ancestor's): every record a known
 *  member with a list of strings, or nothing — a display member must never throw where a card is minted. */
export declare function readAllowRuleShadows(value: unknown): readonly AllowRuleShadow[] | undefined;
/** Why a matched entry did not clear the ask, by the ask's class — one row per class, so a class added later is a
 *  compile error here rather than somebody else's reason on the card. Two facts the ask carries are read first, because
 *  they name the reason more exactly than a class shared by several: a table word (`mandate` — the exact mark) and the
 *  deployment's own authorship (`authoredBy`). */
declare const SHADOW_REASON: {
    readonly content_question: "the call is the engine's own question to a person";
    readonly hook: "a PreToolUse hook asks about this call — the deployment's own screening is answered by a person";
    readonly ancestor: "the task that delegated this one owns this question";
    readonly unverifiable_delete: "this removal could not be verified safe — it is cleared by confirming this call, never by an allow rule";
    readonly transcript_write: "this write targets the session transcript — it is cleared by confirming this call, never by an allow rule";
    readonly org_rule: "an organization policy rule requires approval for this call";
    readonly governance_unavailable: "this deployment is org-governed and cannot currently read its organization policy";
    readonly rule_unreadable: "this call could not be read against a deny or ask rule, so whether one forbids it is unknown";
    readonly ask_rule: string;
    readonly denial_limit_fallback: "the auto-mode classifier refused too many calls in a row, so a person decides";
    readonly requires_user_interaction: "this tool's server declares that a call must be put to a person";
    readonly operator_forced: "this call arrived already marked as requiring confirmation (an earlier layer of this run, or the task that delegated it, judged it so) — it is cleared by confirming this call, never by a standing allow rule";
    readonly shell_floor: string;
    readonly write_protection_unresolved: string;
    readonly probe: string;
    readonly write_protection: string;
    readonly tool_marks_mcp: string;
    readonly tool_marks_a2a: string;
    readonly policy_rra: "the deployment's policy requires a real approval for this call";
    readonly artifact_shared_read: "this read targets another task's shared artifact — it is cleared by confirming this call";
    readonly mode: "the permission mode puts this question to a person";
    readonly unstated: "this call arrived already marked as requiring confirmation (an earlier layer of this run, or the task that delegated it, judged it so) — it is cleared by confirming this call, never by a standing allow rule";
    readonly ordinary: "this call arrived already marked as requiring confirmation (an earlier layer of this run, or the task that delegated it, judged it so) — it is cleared by confirming this call, never by a standing allow rule";
};
/** The fence over the reason table: `never` while every class has a row. */
export type ShadowReasonTableCoversEveryClass = AssertAllKeysHandled<Exclude<AskClass, keyof typeof SHADOW_REASON>>;
/**
 * The disclosure in the sentence a PERSON reads — rendered where a card or a park row is minted, never onto the decision
 * the classifier reads: "<members> match(es) this call but do(es) not clear the ask — <why>".
 */
export declare function allowRuleShadowSentence(shadows: readonly AllowRuleShadow[], ask: {
    askClass?: AskClass;
    mandate?: PersistedRuleMandate;
    authoredBy?: "deployment";
}): string;
/** The card's two disclosure members off a surviving ask, minted at every station that builds an approval request: the
 *  sanitized records, and the message with the sentence rendered onto it. */
export declare function cardDisclosureOf(decision: {
    message?: string;
    allowRuleShadowed?: unknown;
    askClass?: AskClass;
    mandate?: PersistedRuleMandate;
    authoredBy?: "deployment";
}, fallbackMessage: string): {
    message: string;
    allowRuleShadowed?: readonly AllowRuleShadow[];
};
/** The notice for list entries that grant (or refuse) nothing — one code for every list. */
export declare const ALLOWED_TOOL_NOT_GRANTED_CODE = "permission.allowed_tool_not_granted";
/** One entry that reads as nothing, and the list it came from (a skill's names the skill and which of its two lists). */
export type AllowEntryInertNote = {
    readonly source: "skill";
    readonly skill: string;
    readonly list: "allowed-tools" | "disallowed-tools";
    readonly entry: string;
    readonly reason: AllowEntryInertReason;
} | {
    readonly source: AllowEntrySource;
    readonly entry: string;
    readonly reason: AllowEntryInertReason;
};
/**
 * The notice for entries this grammar reads as nothing — delivered only when one exists: once per prepared task for the
 * skill and request lists (`sessionId` given), once per Runner for the deployment's list. The person whose list it is
 * reads it (audience `user`); the run goes on (an entry that grants nothing makes it ask more).
 */
export declare function allowedToolsNotGrantedNotice(inert: readonly AllowEntryInertNote[], sessionId: string | undefined): EngineNotice;
export {};
