/**
 * The tool FACE vocabulary (design/388 §2.1–§2.2): the closed word sets and the small declaration
 * shapes that describe a tool WITHOUT executing it — its display family, the parameter that names its
 * path target, the parameter vocabulary a permission rule may speak about it, the render hints a shell
 * may read, and the mount-condition tags the static catalog lists it under.
 *
 * Layer-0 vocabulary: nothing here reads an env, a deps object, or a tool instance. `ToolSpec`
 * (tool-spec.ts) carries the declaration half of these shapes as optional fields; the static catalog
 * (tool-catalog-entries.ts) lists every built-in's face; the effect roster (tool-roster.ts) reads the
 * same shapes off the MOUNTED instance. One vocabulary, three readers, no second table.
 */
/** The display / dispatch family of a tool. INPUT to grouping and card pre-selection only — never an
 *  authorization source (a `"file-write"` family grants nothing; the path-confinable predicate reads
 *  {@link ToolPathTarget}, and the approval card is chosen by {@link ToolRenderHints.approvalCard}). */
export declare const TOOL_FAMILIES: readonly ["shell", "file-read", "file-write", "search", "web", "delegate", "plan", "scaffold", "memory", "protocol", "other"];
export type ToolFamily = (typeof TOOL_FAMILIES)[number];
/**
 * The closed set of MOUNT-CONDITION tags a static catalog entry is listed under. The static half of the
 * catalog carries an ARRAY (a tool can be mounted by more than one condition — TaskOutput rides both the
 * hand band and the delegation surface); the effect roster records the ONE tag that actually fired.
 *
 *  - `hands` — the hand band (an execution env is wired: `deps.executionEnv` / `executionEnvFactory`);
 *  - `backgroundTasks` — the background-task surface (`Monitor`);
 *  - `workflow` — the workflow tool surface (`Workflow`);
 *  - `delegation` — the union of the background-task and workflow surfaces (TaskOutput/TaskStop/
 *    AgentTranscript, SendMessage's first condition);
 *  - `hostInternals` — a host-internal seat is present (`RunInternals.parentNotify`);
 *  - `peerLane` — the peer-session lane is mounted;
 *  - `scheduler` — the env carries a scheduler daemon (the Cron family + ScheduleWakeup);
 *  - `memory` — an engine-memory / shared-memory session is wired;
 *  - `scenario` — mounted by a HOST scenario factory through `TaskSpec.tools` (core defines the tool,
 *    the host decides to mount it);
 *  - `always` — mounted on every task unless excluded (ReportBlocked/ReportFindings);
 *  - `optional` — mounted by a per-task opt-in or a wired seat (plan mode, an output schema, an
 *    offload store, a question face, a skills listing, an MCP configuration).
 */
export declare const TOOL_MOUNT_TAGS: readonly ["hands", "backgroundTasks", "workflow", "delegation", "hostInternals", "peerLane", "scheduler", "memory", "scenario", "always", "optional"];
export type ToolMountTag = (typeof TOOL_MOUNT_TAGS)[number];
import type { AssertAllKeysHandled } from "./ask-origin.js";
/** The closed set of specialised approval cards a shell may pre-select from a render hint. The hint is a
 *  PRE-FILTER: the shell owns each card's input schema and validates the call's full args before
 *  mounting the card (design/388 §2.5 boundary ①). */
export declare const TOOL_APPROVAL_CARDS: readonly ["file-edit", "file-write", "notebook-edit", "shell", "fetch", "plan", "question", "generic"];
export type ToolApprovalCard = (typeof TOOL_APPROVAL_CARDS)[number];
/** Membership in the closed set — the one screen a stored or declared card word passes before it is read. */
export declare function isToolApprovalCard(word: unknown): word is ToolApprovalCard;
/** The cards only an engine-defined tool owns: a caller or protocol tool cannot declare one, and the card is minted
 *  from the engine's own judgment of the call, never from a row's declaration. */
export declare const RESERVED_APPROVAL_CARDS: readonly ["question", "plan"];
export type ReservedApprovalCard = (typeof RESERVED_APPROVAL_CARDS)[number];
/** How a path-targeting tool touches its target. `read` never enters a write-confinement face. */
export declare const TOOL_PATH_ACCESSES: readonly ["read", "create", "edit"];
export type ToolPathAccess = (typeof TOOL_PATH_ACCESSES)[number];
/**
 * The BASE a RELATIVE spelling in the target slot resolves against — the tool's OWN resolution base,
 * DECLARED so every fence resolves the very path the tool will open instead of guessing one:
 *
 *  - `cwd` — the live tracked working directory, falling back to the task root when no tracker moved
 *    (Read / Edit / Write / NotebookEdit: each hands `cwdRef.current` to `canonicalizeTarget` as its base);
 *  - `root` — the task root, always (Grep / Glob: their `path` describes say "relative to root", and the
 *    tools hand `rootCanonical` to the same resolver whatever the shell's `cd` did).
 *
 * Absent ⇒ `cwd`: the pre-declaration reading every fence took, kept as the floor for a face (a caller's,
 * an MCP server's) that declares no base. This one word is the whole difference the fences had to model,
 * and getting it wrong is SILENT — a rule about the path the tool really opens simply never fires.
 */
export declare const TOOL_PATH_BASES: readonly ["cwd", "root"];
export type ToolPathBase = (typeof TOOL_PATH_BASES)[number];
/**
 * What the call targets when the target slot carries NO usable spelling:
 *
 *  - `none` — nothing. A file tool with no path names no file, so no path rule speaks about the call;
 *  - `base` — the resolution base ITSELF. A search tool with no `path` searches the WHOLE base, so a rule
 *    naming the base (or anything containing it) does reach the call.
 *
 * Absent ⇒ `none` (the pre-declaration reading: an absent slot was "no resolvable path" for every tool).
 */
export declare const TOOL_PATH_ABSENCES: readonly ["none", "base"];
export type ToolPathAbsence = (typeof TOOL_PATH_ABSENCES)[number];
/**
 * The parameter that names a tool's filesystem target, how the target is touched, and how a spelling in that
 * slot RESOLVES — as a READER sees it, whichever side it came from. Present ⇔ the tool can be confirmed BY
 * PATH (write confinement, sensitive-path guards, edited-file tracking, the transcript-directory gate, the
 * permission-rule path family). `param` outranks every alias (NotebookEdit's `notebook_path` beats a decoy
 * `file_path`). `skillScopeEligible` (default false) is a SEPARATE authorization domain (its one reader, the
 * skill-scope write fence, is retired and no reader remains; the bit stays a declared member of the roster row) — a
 * confinable write tool is not automatically eligible there.
 *
 * ONE shape, two spellings: a DECLARATION ({@link ToolPathTarget}, what a catalog row / a `ToolSpec` / an
 * MCP overlay writes) and the roster row's NORMALIZED form (`aliases` always an array, `skillScopeEligible`
 * always a boolean) that the wire carries and the gate stamps on a call. Both are readable through this
 * type, which is what every fence reads — the shape used to be re-declared at each of them, and a member
 * added to one spelling silently never reached the others.
 *
 * The three RESOLUTION members are read by one function (`effectivePathTargetOf`, effective-path-target.ts)
 * that every fence and the tools themselves go through: the declaration is the single source, so a fence
 * and the tool it fences cannot resolve one call to two different files.
 */
export interface ToolCallPathTarget {
    param: string;
    aliases?: readonly string[];
    access: ToolPathAccess;
    skillScopeEligible?: boolean;
    /** How a RELATIVE spelling in `param` (or an alias) resolves. Absent ⇒ `cwd`. */
    base?: ToolPathBase;
    /** What the call targets when the slot is absent. Absent ⇒ `none`. */
    absent?: ToolPathAbsence;
    /**
     * A top-level parameter whose ABSOLUTE glob pattern carries its own base directory (Glob's `pattern`:
     * `/proj/secret/**` searches `/proj/secret` with no `path` at all). Consulted ONLY when the target slot
     * is absent and `absent` is `base` — the tool's own precedence, in which an explicit `path` wins and a
     * relative pattern leaves the base alone.
     */
    patternParam?: string;
}
/** The DECLARATION spelling of {@link ToolCallPathTarget}: what a catalog row, a `ToolSpec` or an MCP
 *  overlay writes. `skillScopeEligible` is narrowed to `true` — a declaration says "eligible" or says
 *  nothing; "eligible: false" is the absence, and spelling it would be a second way to say one thing. */
export interface ToolPathTarget extends ToolCallPathTarget {
    skillScopeEligible?: true;
}
/**
 * The NORMALIZED spelling of {@link ToolCallPathTarget}: what the roster MINTS, what the wire carries, and
 * what the gate stamps on a call. `aliases` and `skillScopeEligible` are always present because the mint
 * fills them — a guarantee a consumer reading a stamped face has always had, and one the shared reader type
 * deliberately does not weaken (an optional member here would break `face.pathTarget.aliases.includes(…)`
 * at compile time for every downstream that already reads it).
 */
export interface ToolRosterPathTarget extends ToolCallPathTarget {
    aliases: readonly string[];
    skillScopeEligible: boolean;
}
/**
 * The SLOT half of a target — which argument names the path — with the RESOLUTION half (`base` / `absent` /
 * `patternParam`) dropped, so the reader falls back to the documented defaults.
 *
 * #635, from the adversarial round: the protective floor (design/388 B6 — a face that declares no target of
 * its own is judged against the CATALOG's declaration for the name) rests on "naming a slot can only TIGHTEN
 * a deny". Naming a slot does. Claiming how a FOREIGN tool of the same name RESOLVES that slot does not: a
 * wrong claim moves the judged path to a different file, and the deny the floor exists to keep then misses.
 * So the floor hands over the slot and keeps its mouth shut about the resolution.
 */
export declare function pathTargetSlotOnly(pt: ToolCallPathTarget): ToolCallPathTarget;
/**
 * The parameter vocabulary a permission rule (`Tool(param:pattern)`) may name. DERIVED by default from
 * the tool's schema: the SCALAR top-level parameters (string/number/integer/boolean and their enum/const/
 * union forms) plus {@link ToolPathTarget.aliases}; object/array parameters never enter (a rule on them
 * can never match — `matchParamRules` skips non-scalar values). A declaration can only NARROW the derived
 * set; `primaryParams` defaults to the path target's `param` + aliases.
 */
export interface ToolRuleFace {
    primaryParams?: readonly string[];
    params?: readonly string[];
}
/** The roster's WIRE bounds on a tool name and a contract member (design/388 §2.5 / B20). Distinct from
 *  protocol-naming's `TOOL_NAME_MAX_CHARS` (64), the provider-facing bound the MCP/A2A namespacing helper
 *  budgets a MINTED name to — a minted name is always inside this wire bound by construction; a CALLER
 *  declaration is judged against it at prepare. */
export declare const TOOL_WIRE_NAME_MAX_CHARS = 128;
/** The roster's wire bound on a SHORT identity member: a contract's `contractId` / `implementationRevision`, and the
 *  `modelGate` class a definition carries. Bounded at the mint (`rosterMemberBoundProblem`), never truncated. */
export declare const TOOL_CONTRACT_MAX_CHARS = 64;
/** The roster's wire bound on a row's `cardId` — a COMPOSITE minted from bounded members, so its bound is DERIVED
 *  from theirs rather than declared beside them: the widest form is `<mcp|a2a>:<peer>/<tool>` with the peer and the
 *  protocol tool segment each inside the wire NAME bound (`builtin:<name>` and `<caller|external>:<contractId>` are
 *  narrower). A row minted from in-bound members therefore fits by construction; the mint's own check on it is a
 *  tripwire for a new source form, never a working rule. */
export declare const TOOL_CARD_ID_MAX_CHARS: number;
/** The roster's wire bound on a KEY — a schema property name, a path-target `param`/alias, a rule-face param. A key is a
 *  SEMANTIC name every fence reads an argument by, so it is never truncated: a declaration over the bound is refused at
 *  the door (caller) or dropped with a disclosed reason (MCP intake), and a row carries every key exactly. */
export declare const TOOL_KEY_MAX_CHARS = 256;
/** The roster's bound on how many top-level keys one row carries (the same refuse/drop treatment). */
export declare const TOOL_KEYS_MAX = 1024;
/** Bounds every render-hint string is held to on the roster (design/388 §2.2 ④). */
export declare const RENDER_HINT_MAX_CHARS = 64;
export declare const RENDER_HINT_ACTIVITY_MAX_CHARS = 32;
export declare const RENDER_HINT_MAX_LIST = 16;
/**
 * Declarative, template-free display hints (design/388 §2.2 ④, D-4). UNTRUSTED display input on the
 * wire: the engine length-caps them at the roster mint; the shell strips control / newline / bidi
 * characters before rendering. `resultCards` may only name cards in the tool's OWN namespace
 * (`caller:<contractId>/<type>`) — engine cards (`builtin:*`, `mcp`, the refusal cards) are minted by
 * the engine alone and a declaration naming one is refused at prepare.
 */
export interface ToolRenderHints {
    userFacingName?: string;
    activity?: string;
    summaryParams?: readonly string[];
    resultCards?: readonly string[];
    /** The card family this tool asks under; absent reads `generic`. `question` / `plan` are the engine's own tools' cards — a declaration of either is refused. */
    approvalCard?: ToolApprovalCard;
}
/**
 * The static FACE of a tool — the subset of `ToolSpec` a catalog entry declares and a definition module
 * spreads into its spec. Everything here is readable without an env or a deps object; the effect roster
 * reads the same members off the mounted instance.
 */
export interface ToolFaceDeclaration {
    family: ToolFamily;
    effect?: import("./tool-spec.js").ToolEffect;
    egress?: true;
    irreversibility?: "never" | "maybe" | "always";
    contentOrigin?: import("./tool-spec.js").ToolContentOrigin;
    contract?: {
        contractId: string;
        implementationRevision: string;
    };
    aliases?: string[];
    pathTarget?: ToolPathTarget;
    /**
     * The rule face ({@link ToolRuleFace}) and, for a definition whose primary parameter is a shell command line, the grammar
     * that judges it — `grammar: "command"`, the SHELL FACE. Every `Bash(<command>)` rule (the command grammar's one spelling,
     * deny / ask / allow, from every source) is judged on a call that answers to the name of such a definition, against that
     * parameter; a bare `Bash` rule stays a rule on the tool of that name. Only a catalog row declares it (a caller's
     * `ToolSpec.ruleFace` is a {@link ToolRuleFace}): the static catalog is the one place the shell face is read from.
     */
    ruleFace?: ToolRuleFace & {
        readonly grammar?: "command";
    };
    renderHints?: ToolRenderHints;
    offload?: boolean;
    offloadThresholdChars?: number;
    compactable?: true;
    budgetExempt?: true;
}
/**
 * The kinds of leg a run can be, as far as which tools a leg itself relies on: a delegated child (every lane a delegation
 * tool, a workflow or a team spawns), a NAMED delegated child (a teammate), an iteration of a goal loop, an observer sidecar,
 * a run with an output schema (it finishes by submitting through the structured-output tool). A catalog row's
 * {@link ToolCatalogEntry.protocol} names the kinds whose legs carry that tool as part of their protocol.
 */
export declare const TOOL_LEG_KINDS: readonly ["delegated", "teammate", "goal", "observer", "structured"];
export type ToolLegKind = (typeof TOOL_LEG_KINDS)[number];
/**
 * One layer of a tool selector, as data: an allowed-tools list (absent = no allowlist on this layer) and a denied-tools list,
 * each a frozen copy of the entries a list was written with. A run's own layer is its `allowTools` and `excludeTools`; the
 * layers above it are the ones the run that spawned it was bounded by, plus that run's own.
 */
export interface ToolSelectorLayer {
    readonly allow?: readonly string[];
    readonly deny: readonly string[];
}
/**
 * The compiled tool selector of one run — the one answer to "is this tool available on this run", read at the roster valve
 * and on every later roster change (an MCP refresh or re-dial, the deferred-search lane), and handed down as the ceiling of
 * every run this one spawns (`layers`). A tool is admitted when it is a protocol tool of this run's leg kind, or when every
 * layer admits it: the layer's allowlist (if any) reaches it and its denylist does not.
 */
export interface ToolSelector {
    readonly layers: readonly ToolSelectorLayer[];
    admits(tool: {
        readonly name: string;
        readonly aliases?: readonly string[];
    }): boolean;
    /** Can ANY tool of the protocol peer whose minted prefix is `prefix` (`mcp__srv__`) be admitted — read off the lists alone,
     *  never off what the peer lists now, so a tool the peer lists later is judged by the same answer. */
    admitsPeer(prefix: string): boolean;
}
/**
 * One row of the static tool catalog (design/388 §2.1 "静态目录"). Keyed by DEFINITION identity, not by
 * name: two definitions may share a wire name (the full and the read-only shell both answer to `Bash`),
 * and every catalog predicate counts a name as a member when ANY entry under it matches.
 */
export interface ToolCatalogEntry {
    /** Definition identity — unique across the catalog (`bash`, `bash-readonly`). */
    id: string;
    /** Wire name; may repeat across entries. */
    name: string;
    /** `builtin` = a core definition mounted by core or by a host factory; `synthetic` = core mints it
     *  per task with a per-task shape (the structured-output tool). */
    source: "builtin" | "synthetic";
    /** Where the definition lives (repo-relative), so a catalog gate can name the file. */
    definedIn: string;
    /** The conditions under which core (or a host scenario) mounts this definition. */
    mountedBy: readonly ToolMountTag[];
    /** The `details.type` cards this definition mints on `tool_end.structured`. */
    cards: readonly string[];
    /** The declared face — spread into the definition's `ToolSpec` by the module that owns it. */
    face: ToolFaceDeclaration;
    /** A `modelGate` class the default-bundle assembler stamps on this definition's default arm. */
    modelGate?: string;
    /** The leg kinds whose legs rely on this tool as part of their protocol: on such a leg the tool's availability is not a
     *  selector's to decide (an allowlist need not name it), and a denylist that reaches it there is a contradiction the run
     *  refuses at prepare. */
    protocol?: readonly ToolLegKind[];
    /** A protocol row the leg shares with the run that spawned it (the team task-list family a teammate shares with its leader): on its
     *  leg the leg's OWN lists do not decide it, but the ceiling still does — the leg holds it exactly when its spawner may. */
    protocolUnderCeiling?: true;
}
/**
 * The band-membership table over the mount tags: a host derives its hand band as the definitions listed under a
 * TRUE row (server B-1). Every tag has a row — the fence reds `tsc` when a tag is added without one. The
 * background-task surface is hands-derived (`backgroundTaskToolsActive` requires the shell), so a definition
 * mounted by it alone is a band member that is NOT dual-use.
 */
export declare const MOUNT_TAG_IN_HANDS_BAND: {
    readonly hands: true;
    readonly backgroundTasks: true;
    readonly workflow: false;
    readonly delegation: true;
    readonly hostInternals: true;
    readonly peerLane: true;
    readonly scheduler: false;
    readonly memory: false;
    readonly scenario: false;
    readonly always: false;
    readonly optional: false;
};
export type HandsBandTableCoversEveryMountTag = AssertAllKeysHandled<Exclude<ToolMountTag, keyof typeof MOUNT_TAG_IN_HANDS_BAND>>;
/** The tags whose definitions form the hand band a host derives (server B-1 `HANDS_BAND_TAGS`). */
export declare const HANDS_BAND_TAGS: ReadonlySet<ToolMountTag>;
