import type { ByteSource } from '../../io/types.ts';
import type { AdmissionRules, Ask, Claimant, CommandContext, CommandRule, Deny, Pending } from '../../policy/index.ts';
import { type EntryGate } from '../../policy/types.ts';
import type { TSNodeLike } from '../../shell/types.ts';
import { PathSpec, type Refusal } from '../../types.ts';
import type { NamespaceLinks } from '../../view/types.ts';
import type { Namespace } from '../mount/namespace/namespace.ts';
import type { MountRegistry } from '../mount/registry.ts';
import type { SessionState } from '../session/session.ts';
import { type Word } from './inner_lines.ts';
/**
 * What the command plane prints when a line does not get to run: 126 for
 * a whole-command refusal or an unanswered ask, the operand code (1, tar
 * 2) for a refusal about a path or carrying an error. `refusal` is the
 * record the result carries beside stderr, null for the filesystem's own
 * error. Mirrors the Python `Refused`.
 */
export interface Refused {
    readonly stderr: Uint8Array;
    readonly exitCode: number;
    readonly refusal: Refusal | null;
}
/**
 * A command the gate let through, and what its own I/O may touch.
 *
 * The gate judged the paths the line names; a walk below them reaches
 * entries no rule has seen, so the dispatcher binds this to the session
 * context for the command's run and the commands tier asks it before each
 * read, write or listing (`EntryGate`). The paths the gate already judged
 * pass, since the line was admitted on them; every other entry is judged
 * by `ioRefusal` under the same precedence the gate applied to the line,
 * and a refusal is the dispatcher's `PolicyDenied` (EACCES, the path, the
 * reason on its record), which every command renders as GNU's
 * `Permission denied`.
 * `granted` holds the ask rules the line runs under a grant for: the one
 * the entry point answered for this line, and the session's standing ones.
 * `ctx` is what `preCommand` judged the command on, which `postCommand`
 * extends with what came back.
 */
export declare class Admitted implements EntryGate {
    readonly rules: AdmissionRules | null;
    readonly ctx: CommandContext;
    readonly judged: ReadonlySet<string>;
    readonly granted: readonly CommandRule[];
    constructor(init: {
        rules: AdmissionRules | null;
        ctx: CommandContext;
        judged: ReadonlySet<string>;
        granted: readonly CommandRule[];
    });
    check(virtual: string): void;
    scopes(virtual: string): boolean;
    refusal(virtual: string): string | null;
}
/**
 * The paths a path-pattern guard reads for a line: the operands as
 * typed and the values of path-valued flags, a command tree's group and
 * leaf options among them (`treeFlags`, from `treePathScopes`), then, for
 * a command that
 * follows links, the targets they resolve to. `cat /data/link` reads
 * `/data/secret`, so a rule protecting the target has to see it, and a
 * command-scoped rule never runs at the dispatcher where the resolved path
 * would otherwise be checked. The links are followed as the command's own
 * session sees them (`links`, `Namespace.sessionLinks`), as the router
 * follows them: on the browser fallback the ambient view folds every live
 * session's hides, and a peer hiding the link must not keep its target from
 * the rule; null where no link stands. The follow policy is the command's own
 * (`follows`, whether `LineFacts.follows` is not NONE: rm, mv, ln, stat,
 * tar ... act on the link itself, `-L` turns following back on), the same
 * one the router applies to the operands before the handler runs, so a rule
 * sees exactly the path the command will touch. A loop is left to that later
 * step to report; here the typed paths stand. Then the operand a bare
 * `ls`/`find`/`du`/`tree`/`grep -r` implies, the working directory,
 * which the executor injects after the gate and which a rule on that
 * directory has to see. Last come the statement's redirect targets:
 * `cat < /data/secret` reads the file and `echo x > /data/secret`
 * truncates it, on the shell's own fds outside the admitted command's
 * gate window, so the admission is the one place a rule can see them. A
 * redirect always dereferences (the shell opens the target), so its
 * link targets ride along whatever the command's own follow policy
 * says.
 */
export declare function policyScopes(name: string, args: readonly string[], operands: readonly (string | PathSpec)[], follows: boolean, links: NamespaceLinks | null, cwd: string, implied?: PathSpec | null, redirects?: readonly PathSpec[], treeFlags?: readonly PathSpec[]): PathSpec[];
/**
 * The command plane's admission of one command: the policy chain, then
 * the approval ledger. The one gate every command class passes through,
 * in the tree (`runArgv`, once the words are expanded) and for a line a
 * runtime takes whole (`admitLine`, per parsed command). A word the
 * session's allow list leaves out is the profile's Deny, like any other
 * rule's; a path the session cannot see is
 * dropped before any method, so a rule never names it and the dispatcher
 * answers ENOENT; a Deny renders in the outcome table's voice; an Ask
 * is answered by the entry point from the session's grants or the host.
 * `stdin` decides whether a bare `rg` reads the working directory.
 */
/**
 * One command's literal words, classified the way the runtime would
 * classify them, so the gate and the run name the same paths.
 */
export declare function classifiedWords(name: string, args: readonly string[], session: SessionState, registry: MountRegistry): Promise<(string | PathSpec)[]>;
/**
 * The paths a statement's redirect targets name.
 *
 * Shared by admission and by the dry run, because a rule reads a
 * redirect the same way in both: a target only the runtime can expand
 * names no path here, and one that is not path-shaped is not a file.
 */
export declare function redirectPaths(words: readonly Word[], registry: MountRegistry, cwd: string): PathSpec[];
/**
 * Everything the gate decides about one command before anything is
 * spent on it: the classified context, and the policy chain's answer (the
 * first Deny, else the first Ask) with the answers it came from.
 *
 * Split out of `admit` so a dry run can have the answer without the
 * consequences. Nothing here records a request, consumes a grant or
 * reaches the host, which is what makes it safe for `explain`;
 * `admit` adds exactly those and renders.
 *
 * `intrinsic` keeps shell-provided operations subject to tool allow lists
 * even when a function shadows their policy name. `unread` holds the
 * virtual paths a reader of the line's text cannot vouch for: what a word
 * only the runtime expands names, or a relative word after a `cd` it
 * could not follow. No policy is shown them; the per-command gate reads
 * the real ones and passes none. `every` asks every policy past a Deny,
 * for `explain`; the gate's own answers end at the first Deny.
 * `rulesOnly` asks the profile's rules alone, for a pass that judges a line
 * before it runs; a policy's own `preCommand` is asked once, by the gate
 * that runs the command. `line` is the line the command was parsed from,
 * empty outside a line.
 */
/**
 * Whether the allow list refuses a CLI that reaches a service. Such a CLI
 * (an account or script CLI) reaches its service by id, past every hide, so
 * under a profile that hides paths it runs only where a pattern starting
 * with its own name matches the line. `*` and a pattern for another of its
 * verbs do not count. Mirrors the Python `unlisted_service`.
 */
export declare function unlistedService(ctx: CommandContext, registry: MountRegistry, session: SessionState): boolean;
export declare function gate(name: string, args: readonly string[], operands: readonly (string | PathSpec)[], session: SessionState, registry: MountRegistry, namespace: Namespace | null, stdin?: ByteSource | null, redirects?: readonly PathSpec[], intrinsic?: boolean, unread?: ReadonlySet<string>, every?: boolean, rulesOnly?: boolean, line?: string): Promise<[CommandContext, Deny | Ask | null, (Deny | Ask)[]]>;
/**
 * The chain's answer once the ledger has had its say. An Ask is the chain's
 * answer only after every Deny had its say; the ledger answers it from the
 * session's records or the host, so an answer never re-opens a deny. A wait
 * the run's kill cut short is the kill landing late, not a ruling, so it
 * throws as every other abandoned wait does rather than being rendered as a
 * refusal the document never made. Mirrors the Python `resolved`.
 */
export declare function resolved(ctx: CommandContext, asked: Deny | Ask | null, registry: MountRegistry, signal: AbortSignal | undefined, claimant: Claimant | null): Promise<Deny | Pending | null>;
export declare function admit(name: string, args: readonly string[], operands: readonly (string | PathSpec)[], session: SessionState, registry: MountRegistry, namespace: Namespace | null, stdin?: ByteSource | null, redirects?: readonly PathSpec[], signal?: AbortSignal, claimant?: Claimant | null, intrinsic?: boolean, unread?: ReadonlySet<string>, rulesOnly?: boolean): Promise<Refused | Admitted>;
/**
 * Admit a `[ ]` test, or one `[[ ]]` leaf, as the command it is: the shell
 * evaluates it itself, so no command gate saw its words, and a rule, an allow
 * list or a policy answers it by its own name as it answers `test` on the
 * same words. `name` is `[` or `[[`; `words` what it tests, expanded,
 * operators included; `signal` the run's abort signal; `claimant` the test
 * and its line, null outside a line. Throws `CondRefused` where the gate
 * refused it. Mirrors Python's admit_test.
 */
export declare function admitTest(name: string, words: string[], session: SessionState, registry: MountRegistry, namespace: Namespace | null, signal?: AbortSignal, claimant?: Claimant | null): Promise<Admitted>;
/** Mark redirected input without opening or expanding its source. */
export declare function statementStdin(node: TSNodeLike): Uint8Array | null;
export declare function statementRedirects(node: TSNodeLike, home: string | null): Word[];
//# sourceMappingURL=admission.d.ts.map