import { type ProtocolNamespace } from "./protocol-table.js";
/**
 * RB-476-A stage 2 (ruling 2026-08-02, RB-476 "no compatibility surface survives", replay
 * resolution included) — the durable-name machinery this module used to hold is RETIRED:
 *
 *  - `OLD_TO_NEW` (the Q6/design-108/design-115 persisted-name normalization) and the MCP `mcp__`
 *    prefix arm are gone: a persisted checkpoint/orphan/policy entry carrying a pre-rename name no
 *    longer resolves to the live roster. Old durable state misses LOUDLY (`resume.tool_unavailable`
 *    on a resumed checkpoint, a roster miss on replay) — by ruling, old sessions are sacrificed
 *    rather than carried.
 *  - `canonicalToolName` is gone with it: with the mapping cleared it was the identity function, and
 *    keeping an identity shim invites the next mapping to grow back silently.
 *  - `TOMBSTONED_TOOLS` (a second table of per-name re-education prose) is gone. A CALL to a retired name is
 *    told what the one table here says about it ({@link judgeToolNameMiss}): the miss is `expected-absent`
 *    with the successor, where any other unknown name stays the generic roster miss.
 *
 * What REMAINS is validation data: {@link RETIRED_TOOL_NAMES} maps every name the engine ever
 * retired to a one-line guidance string, and {@link judgeRuleToolName} is the ONE reading of it a rule's
 * tool name gets. They exist because deleting the mapping flips stale POLICY entries from "silently
 * matched" to "silently matches nothing" — and for a deny/requireApproval entry that direction WIDENS
 * the surface. `validatePermissionRules` (permission-rules.ts) does NOT classify retired names itself:
 * which names a deployment mounts its OWN tool under is a roster fact, and the judgment takes the roster.
 * A deployment that mounts its OWN tool under one of these names is unaffected: the name is then in the
 * roster and the judgment answers `current`.
 *
 * GRAMMAR of a guidance string, read by {@link judgeRuleToolName} and held by a pin: it opens with
 * `renamed "<name>"` (a 1:1 successor — the judgment's `currentName`), `folded into "<name>"` (merged into a
 * wider tool: writing it would deny more than the entry did, so it is no current name), or `removed — `.
 */
export declare const RETIRED_TOOL_NAMES: ReadonlyMap<string, string>;
/** The four answers {@link judgeRuleToolName} gives — a closed set. */
export declare const RULE_TOOL_NAME_VERDICTS: readonly ["current", "retired", "unprefixed_namespace", "unmintable_segment"];
/**
 * Whether a tool name written in a rule is a stale name — one that, against `roster`, names no tool and never can:
 *  - `current` — not a stale name: the roster mounts it, or it is none of the three below. (Whether a current name matches
 *    anything THIS run is a different question — an unknown name is the prepare audit's advisory.)
 *  - `retired` — a name in {@link RETIRED_TOOL_NAMES} the roster does not mount; `guidance` is that table's line, and
 *    `currentName` the 1:1 successor when there is one (see the module header's grammar).
 *  - `unprefixed_namespace` — carries the `__` namespace separator with no protocol prefix. The roster cannot clear it:
 *    a caller tool name or alias carrying `__` is refused at prepare, every engine tool name is `__`-free, and every
 *    protocol tool is minted with its prefix.
 *  - `unmintable_segment` — carries a protocol prefix, but a segment of it is not one the mint produces: the peer segment
 *    (the server / remote agent) is empty or not a spelling the mint produces for any peer (the name is read as written —
 *    peers compare exactly — and every mounted tool carries the minted spelling, so the name reaches none of them), or the
 *    tool segment is EMPTY (a trailing separator, `mcp__srv__`: no tool is minted under an empty segment). `guidance` says
 *    so in one line; `currentName` is the whole name rewritten with the spelling the mint produces (`mcp__github.com__*` →
 *    `mcp__github_com__*`), absent when a segment is empty and there is nothing to rewrite. A tool segment that is not empty
 *    is never judged: it is a literal tool name or a glob over one, and an unmatched one is the audit's advisory.
 *
 * `roster` = the tool names (aliases included) the reader knows are mounted: a run's assembled roster at prepare, the
 * names a deployment DECLARES it mounts its own tools under at a session-rule store (an empty set when it declares none).
 */
export type RuleToolNameVerdict = {
    readonly kind: "current";
} | {
    readonly kind: "retired";
    readonly guidance: string;
    readonly currentName?: string;
} | {
    readonly kind: "unprefixed_namespace";
} | {
    readonly kind: "unmintable_segment";
    readonly guidance: string;
    readonly currentName?: string;
};
/**
 * A name in ANY protocol namespace split into its owning namespace, its peer segment and its optional tool segment —
 * CC `rP` (:70710) verbatim, re-anchored on the {@link protocolOf} lookup instead of CC's literal `"mcp"` first split element.
 * `undefined` for a name that is not namespaced (no protocol prefix). The peer is the first segment — EMPTY for `mcp____x` and
 * for the bare prefix, which name no peer; the tool segment is the REST of the split rejoined, so a tool whose minted segment
 * itself carries the separator (charset normalization maps `get..issue` → `get__issue`) decomposes back to one tool name, and
 * is absent when the name stops at the peer (`mcp__srv`) and EMPTY when it ends in a trailing separator (`mcp__srv__`). The
 * one decomposition: the judgment, the covering matcher and the allow-entry grammar all read a namespaced name through it.
 */
export declare function splitNamespacedName(name: string): {
    readonly ns: ProtocolNamespace;
    readonly peer: string;
    readonly tool?: string;
} | undefined;
/** See {@link RuleToolNameVerdict}. Pure; the one answer to "is this rule's tool name a name that reaches no tool". */
export declare function judgeRuleToolName(name: string, roster: ReadonlySet<string>): RuleToolNameVerdict;
/** The two kinds of tool-name miss — a closed set. `unknown`: the name is none the engine ever mounted (a typo, a
 *  guess). `expected-absent`: the name is one the engine RETIRED ({@link RETIRED_TOOL_NAMES}), so its absence is no
 *  surprise and the table says what replaced it (CC 2.1.296 spells the same two words for its render-time miss). */
export declare const TOOL_MISS_KINDS: readonly ["unknown", "expected-absent"];
declare const UNKNOWN_MISS: "unknown", ABSENT_MISS: "expected-absent";
/** What {@link judgeToolNameMiss} answers: the kind (a {@link TOOL_MISS_KINDS} word) and, for `expected-absent`, the clause. */
export type ToolNameMiss = {
    readonly kind: typeof UNKNOWN_MISS;
} | {
    readonly kind: typeof ABSENT_MISS;
    readonly detail: string;
    readonly successor?: string;
};
/**
 * The answer to "a call named `name` matched nothing in `roster`" — the ONE place a tool-call miss is classified:
 * `expected-absent` (with the model-facing `detail`) for a retired name, `unknown` for everything else. It reads the
 * table through {@link judgeRuleToolName}, so a rule's tool name and a call's tool name are judged by the same reading.
 * The detail is the successor (`renamed "<name>"`) when the table names one AND this run mounts it — a successor the
 * roster lacks (plan mode, no shell) is named as unavailable, never offered as the way forward, and is not returned as
 * `successor` — else the table's own line (`folded into …` / `removed — …`), the grammar in the module header.
 */
export declare function judgeToolNameMiss(name: string, roster: ReadonlySet<string>): ToolNameMiss;
/** The names a run mounts — every tool's primary name and its aliases: the roster {@link judgeRuleToolName} is given. */
export declare function mountedToolNames(tools: ReadonlyArray<{
    readonly name: string;
    readonly aliases?: readonly string[];
}>): Set<string>;
export {};
