import { Type, type Static, type TSchema } from "typebox";
import type { AgentTool } from "../internal/harness-types.js";
import { type ReservedApprovalCard, type ToolApprovalCard, type ToolFamily, type ToolRosterPathTarget, type ToolMountTag, type ToolPathTarget, type ToolRenderHints, type ToolRuleFace } from "./tool-face.js";
import type { ToolContentOrigin, ToolEffect } from "./tool-spec.js";
export declare const ROSTER_SOURCES: readonly ["builtin", "caller", "host", "mcp", "a2a", "external", "synthetic"];
export type RosterSource = (typeof ROSTER_SOURCES)[number];
export declare const ToolRosterRenderHints: Type.TObject<{
    userFacingName: Type.TOptional<Type.TString>;
    activity: Type.TOptional<Type.TString>;
    summaryParams: Type.TOptional<Type.TArray<Type.TString>>;
    resultCards: Type.TOptional<Type.TArray<Type.TString>>;
    approvalCard: Type.TOptional<Type.TUnion<[Type.TLiteral<"file-edit">, Type.TLiteral<"file-write">, Type.TLiteral<"notebook-edit">, Type.TLiteral<"shell">, Type.TLiteral<"fetch">, Type.TLiteral<"plan">, Type.TLiteral<"question">, Type.TLiteral<"generic">]>>;
}>;
export declare const ToolRosterEntry: Type.TObject<{
    name: Type.TString;
    /** Always present (empty when the tool answers to no other name). */
    aliases: Type.TArray<Type.TString>;
    source: Type.TUnion<[Type.TLiteral<"builtin">, Type.TLiteral<"caller">, Type.TLiteral<"host">, Type.TLiteral<"mcp">, Type.TLiteral<"a2a">, Type.TLiteral<"external">, Type.TLiteral<"synthetic">]>;
    /** Present iff `source` ∈ {mcp, a2a, external} (run-time validated at the mint). */
    origin: Type.TOptional<Type.TObject<{
        peer: Type.TString;
        declaredBy: Type.TOptional<Type.TUnion<[Type.TLiteral<"center">, Type.TLiteral<"file">, Type.TLiteral<"request">]>>;
    }>>;
    /** Undeclared ⇒ `legacy:<shapeDigest>` / `unversioned`. */
    contract: Type.TObject<{
        contractId: Type.TString;
        implementationRevision: Type.TString;
    }>;
    shapeDigest: Type.TString;
    wireSchemaDigest: Type.TString;
    /** `builtin:<name>` | `caller:<contractId>` | `mcp:<peer>/<tool>` | `a2a:<peer>/<skill>` | `external:<contractId>`. */
    cardId: Type.TString;
    /** ENGINE-minted: sha256 prefix over the canonical tuple {source, peer, name, contractId}; unique per leg. */
    capabilityId: Type.TString;
    /** The materialized schema's top-level properties (name + coarse type). */
    inputKeys: Type.TArray<Type.TObject<{
        name: Type.TString;
        type: Type.TUnion<[Type.TLiteral<"string">, Type.TLiteral<"number">, Type.TLiteral<"integer">, Type.TLiteral<"boolean">, Type.TLiteral<"object">, Type.TLiteral<"array">, Type.TLiteral<"null">, Type.TLiteral<"mixed">]>;
    }>>;
    effect: Type.TUnion<[Type.TLiteral<"read">, Type.TLiteral<"write">, Type.TLiteral<"idempotent">]>;
    effectProvenance: Type.TUnion<[Type.TLiteral<"declared">, Type.TLiteral<"caller">, Type.TLiteral<"synthetic">, Type.TLiteral<"default">]>;
    offload: Type.TBoolean;
    offloadThresholdChars: Type.TOptional<Type.TInteger>;
    compactable: Type.TBoolean;
    budgetExempt: Type.TBoolean;
    egress: Type.TBoolean;
    egressProvenance: Type.TUnion<[Type.TLiteral<"declared">, Type.TLiteral<"caller">, Type.TLiteral<"default">]>;
    irreversibility: Type.TOptional<Type.TUnion<[Type.TLiteral<"never">, Type.TLiteral<"maybe">, Type.TLiteral<"always">]>>;
    reversibilityProbe: Type.TBoolean;
    contentOrigin: Type.TUnion<[Type.TLiteral<"local">, Type.TLiteral<"execution">, Type.TLiteral<"external">]>;
    contentOriginProvenance: Type.TUnion<[Type.TLiteral<"declared">, Type.TLiteral<"server">, Type.TLiteral<"exempted">, Type.TLiteral<"default">]>;
    family: Type.TUnion<[Type.TLiteral<"shell">, Type.TLiteral<"file-read">, Type.TLiteral<"file-write">, Type.TLiteral<"search">, Type.TLiteral<"web">, Type.TLiteral<"delegate">, Type.TLiteral<"plan">, Type.TLiteral<"scaffold">, Type.TLiteral<"memory">, Type.TLiteral<"protocol">, Type.TLiteral<"other">]>;
    pathTarget: Type.TOptional<Type.TObject<{
        param: Type.TString;
        aliases: Type.TArray<Type.TString>;
        access: Type.TUnion<[Type.TLiteral<"read">, Type.TLiteral<"create">, Type.TLiteral<"edit">]>;
        skillScopeEligible: Type.TBoolean;
        base: Type.TOptional<Type.TUnion<[Type.TLiteral<"cwd">, Type.TLiteral<"root">]>>;
        absent: Type.TOptional<Type.TUnion<[Type.TLiteral<"none">, Type.TLiteral<"base">]>>;
        patternParam: Type.TOptional<Type.TString>;
    }>>;
    ruleFace: Type.TObject<{
        primaryParams: Type.TArray<Type.TString>;
        params: Type.TArray<Type.TString>;
    }>;
    approvalPreview: Type.TBoolean;
    validateInput: Type.TBoolean;
    deferred: Type.TBoolean;
    alwaysLoad: Type.TBoolean;
    /** Present iff the definition carries a model-gate class and survived the gate. */
    modelGate: Type.TOptional<Type.TString>;
    renderHints: Type.TOptional<Type.TObject<{
        userFacingName: Type.TOptional<Type.TString>;
        activity: Type.TOptional<Type.TString>;
        summaryParams: Type.TOptional<Type.TArray<Type.TString>>;
        resultCards: Type.TOptional<Type.TArray<Type.TString>>;
        approvalCard: Type.TOptional<Type.TUnion<[Type.TLiteral<"file-edit">, Type.TLiteral<"file-write">, Type.TLiteral<"notebook-edit">, Type.TLiteral<"shell">, Type.TLiteral<"fetch">, Type.TLiteral<"plan">, Type.TLiteral<"question">, Type.TLiteral<"generic">]>>;
    }>>;
    /** The ONE mount condition that fired for this instance. */
    mountedBy: Type.TUnion<[Type.TLiteral<"hands">, Type.TLiteral<"backgroundTasks">, Type.TLiteral<"workflow">, Type.TLiteral<"delegation">, Type.TLiteral<"hostInternals">, Type.TLiteral<"peerLane">, Type.TLiteral<"scheduler">, Type.TLiteral<"memory">, Type.TLiteral<"scenario">, Type.TLiteral<"always">, Type.TLiteral<"optional">]>;
}>;
export type ToolRosterEntry = Static<typeof ToolRosterEntry>;
export declare const ToolRoster: Type.TObject<{
    schemaVersion: Type.TLiteral<1>;
    /** Run-time asserted equal to `entries.length`. */
    count: Type.TInteger;
    /** Declaration order = the model's `tools[]` order; names unique (run-time asserted). */
    entries: Type.TArray<Type.TObject<{
        name: Type.TString;
        /** Always present (empty when the tool answers to no other name). */
        aliases: Type.TArray<Type.TString>;
        source: Type.TUnion<[Type.TLiteral<"builtin">, Type.TLiteral<"caller">, Type.TLiteral<"host">, Type.TLiteral<"mcp">, Type.TLiteral<"a2a">, Type.TLiteral<"external">, Type.TLiteral<"synthetic">]>;
        /** Present iff `source` ∈ {mcp, a2a, external} (run-time validated at the mint). */
        origin: Type.TOptional<Type.TObject<{
            peer: Type.TString;
            declaredBy: Type.TOptional<Type.TUnion<[Type.TLiteral<"center">, Type.TLiteral<"file">, Type.TLiteral<"request">]>>;
        }>>;
        /** Undeclared ⇒ `legacy:<shapeDigest>` / `unversioned`. */
        contract: Type.TObject<{
            contractId: Type.TString;
            implementationRevision: Type.TString;
        }>;
        shapeDigest: Type.TString;
        wireSchemaDigest: Type.TString;
        /** `builtin:<name>` | `caller:<contractId>` | `mcp:<peer>/<tool>` | `a2a:<peer>/<skill>` | `external:<contractId>`. */
        cardId: Type.TString;
        /** ENGINE-minted: sha256 prefix over the canonical tuple {source, peer, name, contractId}; unique per leg. */
        capabilityId: Type.TString;
        /** The materialized schema's top-level properties (name + coarse type). */
        inputKeys: Type.TArray<Type.TObject<{
            name: Type.TString;
            type: Type.TUnion<[Type.TLiteral<"string">, Type.TLiteral<"number">, Type.TLiteral<"integer">, Type.TLiteral<"boolean">, Type.TLiteral<"object">, Type.TLiteral<"array">, Type.TLiteral<"null">, Type.TLiteral<"mixed">]>;
        }>>;
        effect: Type.TUnion<[Type.TLiteral<"read">, Type.TLiteral<"write">, Type.TLiteral<"idempotent">]>;
        effectProvenance: Type.TUnion<[Type.TLiteral<"declared">, Type.TLiteral<"caller">, Type.TLiteral<"synthetic">, Type.TLiteral<"default">]>;
        offload: Type.TBoolean;
        offloadThresholdChars: Type.TOptional<Type.TInteger>;
        compactable: Type.TBoolean;
        budgetExempt: Type.TBoolean;
        egress: Type.TBoolean;
        egressProvenance: Type.TUnion<[Type.TLiteral<"declared">, Type.TLiteral<"caller">, Type.TLiteral<"default">]>;
        irreversibility: Type.TOptional<Type.TUnion<[Type.TLiteral<"never">, Type.TLiteral<"maybe">, Type.TLiteral<"always">]>>;
        reversibilityProbe: Type.TBoolean;
        contentOrigin: Type.TUnion<[Type.TLiteral<"local">, Type.TLiteral<"execution">, Type.TLiteral<"external">]>;
        contentOriginProvenance: Type.TUnion<[Type.TLiteral<"declared">, Type.TLiteral<"server">, Type.TLiteral<"exempted">, Type.TLiteral<"default">]>;
        family: Type.TUnion<[Type.TLiteral<"shell">, Type.TLiteral<"file-read">, Type.TLiteral<"file-write">, Type.TLiteral<"search">, Type.TLiteral<"web">, Type.TLiteral<"delegate">, Type.TLiteral<"plan">, Type.TLiteral<"scaffold">, Type.TLiteral<"memory">, Type.TLiteral<"protocol">, Type.TLiteral<"other">]>;
        pathTarget: Type.TOptional<Type.TObject<{
            param: Type.TString;
            aliases: Type.TArray<Type.TString>;
            access: Type.TUnion<[Type.TLiteral<"read">, Type.TLiteral<"create">, Type.TLiteral<"edit">]>;
            skillScopeEligible: Type.TBoolean;
            base: Type.TOptional<Type.TUnion<[Type.TLiteral<"cwd">, Type.TLiteral<"root">]>>;
            absent: Type.TOptional<Type.TUnion<[Type.TLiteral<"none">, Type.TLiteral<"base">]>>;
            patternParam: Type.TOptional<Type.TString>;
        }>>;
        ruleFace: Type.TObject<{
            primaryParams: Type.TArray<Type.TString>;
            params: Type.TArray<Type.TString>;
        }>;
        approvalPreview: Type.TBoolean;
        validateInput: Type.TBoolean;
        deferred: Type.TBoolean;
        alwaysLoad: Type.TBoolean;
        /** Present iff the definition carries a model-gate class and survived the gate. */
        modelGate: Type.TOptional<Type.TString>;
        renderHints: Type.TOptional<Type.TObject<{
            userFacingName: Type.TOptional<Type.TString>;
            activity: Type.TOptional<Type.TString>;
            summaryParams: Type.TOptional<Type.TArray<Type.TString>>;
            resultCards: Type.TOptional<Type.TArray<Type.TString>>;
            approvalCard: Type.TOptional<Type.TUnion<[Type.TLiteral<"file-edit">, Type.TLiteral<"file-write">, Type.TLiteral<"notebook-edit">, Type.TLiteral<"shell">, Type.TLiteral<"fetch">, Type.TLiteral<"plan">, Type.TLiteral<"question">, Type.TLiteral<"generic">]>>;
        }>>;
        /** The ONE mount condition that fired for this instance. */
        mountedBy: Type.TUnion<[Type.TLiteral<"hands">, Type.TLiteral<"backgroundTasks">, Type.TLiteral<"workflow">, Type.TLiteral<"delegation">, Type.TLiteral<"hostInternals">, Type.TLiteral<"peerLane">, Type.TLiteral<"scheduler">, Type.TLiteral<"memory">, Type.TLiteral<"scenario">, Type.TLiteral<"always">, Type.TLiteral<"optional">]>;
    }>>;
    /** sha256 prefix over the canonical COMPLETE rows — any axis / hint / contract / alias change moves it. */
    digest: Type.TString;
}>;
export type ToolRoster = Static<typeof ToolRoster>;
export declare const ToolRosterDelta: Type.TObject<{
    /** The digest the consumer is expected to hold. A mismatch is NOT a rejection: the carried `roster` is the
     *  new state regardless, only `summary` becomes unusable (the consumer records a skew and re-syncs). */
    fromDigest: Type.TString;
    /** The whole post-change roster; positions come from it, never from the summary. */
    roster: Type.TObject<{
        schemaVersion: Type.TLiteral<1>;
        /** Run-time asserted equal to `entries.length`. */
        count: Type.TInteger;
        /** Declaration order = the model's `tools[]` order; names unique (run-time asserted). */
        entries: Type.TArray<Type.TObject<{
            name: Type.TString;
            /** Always present (empty when the tool answers to no other name). */
            aliases: Type.TArray<Type.TString>;
            source: Type.TUnion<[Type.TLiteral<"builtin">, Type.TLiteral<"caller">, Type.TLiteral<"host">, Type.TLiteral<"mcp">, Type.TLiteral<"a2a">, Type.TLiteral<"external">, Type.TLiteral<"synthetic">]>;
            /** Present iff `source` ∈ {mcp, a2a, external} (run-time validated at the mint). */
            origin: Type.TOptional<Type.TObject<{
                peer: Type.TString;
                declaredBy: Type.TOptional<Type.TUnion<[Type.TLiteral<"center">, Type.TLiteral<"file">, Type.TLiteral<"request">]>>;
            }>>;
            /** Undeclared ⇒ `legacy:<shapeDigest>` / `unversioned`. */
            contract: Type.TObject<{
                contractId: Type.TString;
                implementationRevision: Type.TString;
            }>;
            shapeDigest: Type.TString;
            wireSchemaDigest: Type.TString;
            /** `builtin:<name>` | `caller:<contractId>` | `mcp:<peer>/<tool>` | `a2a:<peer>/<skill>` | `external:<contractId>`. */
            cardId: Type.TString;
            /** ENGINE-minted: sha256 prefix over the canonical tuple {source, peer, name, contractId}; unique per leg. */
            capabilityId: Type.TString;
            /** The materialized schema's top-level properties (name + coarse type). */
            inputKeys: Type.TArray<Type.TObject<{
                name: Type.TString;
                type: Type.TUnion<[Type.TLiteral<"string">, Type.TLiteral<"number">, Type.TLiteral<"integer">, Type.TLiteral<"boolean">, Type.TLiteral<"object">, Type.TLiteral<"array">, Type.TLiteral<"null">, Type.TLiteral<"mixed">]>;
            }>>;
            effect: Type.TUnion<[Type.TLiteral<"read">, Type.TLiteral<"write">, Type.TLiteral<"idempotent">]>;
            effectProvenance: Type.TUnion<[Type.TLiteral<"declared">, Type.TLiteral<"caller">, Type.TLiteral<"synthetic">, Type.TLiteral<"default">]>;
            offload: Type.TBoolean;
            offloadThresholdChars: Type.TOptional<Type.TInteger>;
            compactable: Type.TBoolean;
            budgetExempt: Type.TBoolean;
            egress: Type.TBoolean;
            egressProvenance: Type.TUnion<[Type.TLiteral<"declared">, Type.TLiteral<"caller">, Type.TLiteral<"default">]>;
            irreversibility: Type.TOptional<Type.TUnion<[Type.TLiteral<"never">, Type.TLiteral<"maybe">, Type.TLiteral<"always">]>>;
            reversibilityProbe: Type.TBoolean;
            contentOrigin: Type.TUnion<[Type.TLiteral<"local">, Type.TLiteral<"execution">, Type.TLiteral<"external">]>;
            contentOriginProvenance: Type.TUnion<[Type.TLiteral<"declared">, Type.TLiteral<"server">, Type.TLiteral<"exempted">, Type.TLiteral<"default">]>;
            family: Type.TUnion<[Type.TLiteral<"shell">, Type.TLiteral<"file-read">, Type.TLiteral<"file-write">, Type.TLiteral<"search">, Type.TLiteral<"web">, Type.TLiteral<"delegate">, Type.TLiteral<"plan">, Type.TLiteral<"scaffold">, Type.TLiteral<"memory">, Type.TLiteral<"protocol">, Type.TLiteral<"other">]>;
            pathTarget: Type.TOptional<Type.TObject<{
                param: Type.TString;
                aliases: Type.TArray<Type.TString>;
                access: Type.TUnion<[Type.TLiteral<"read">, Type.TLiteral<"create">, Type.TLiteral<"edit">]>;
                skillScopeEligible: Type.TBoolean;
                base: Type.TOptional<Type.TUnion<[Type.TLiteral<"cwd">, Type.TLiteral<"root">]>>;
                absent: Type.TOptional<Type.TUnion<[Type.TLiteral<"none">, Type.TLiteral<"base">]>>;
                patternParam: Type.TOptional<Type.TString>;
            }>>;
            ruleFace: Type.TObject<{
                primaryParams: Type.TArray<Type.TString>;
                params: Type.TArray<Type.TString>;
            }>;
            approvalPreview: Type.TBoolean;
            validateInput: Type.TBoolean;
            deferred: Type.TBoolean;
            alwaysLoad: Type.TBoolean;
            /** Present iff the definition carries a model-gate class and survived the gate. */
            modelGate: Type.TOptional<Type.TString>;
            renderHints: Type.TOptional<Type.TObject<{
                userFacingName: Type.TOptional<Type.TString>;
                activity: Type.TOptional<Type.TString>;
                summaryParams: Type.TOptional<Type.TArray<Type.TString>>;
                resultCards: Type.TOptional<Type.TArray<Type.TString>>;
                approvalCard: Type.TOptional<Type.TUnion<[Type.TLiteral<"file-edit">, Type.TLiteral<"file-write">, Type.TLiteral<"notebook-edit">, Type.TLiteral<"shell">, Type.TLiteral<"fetch">, Type.TLiteral<"plan">, Type.TLiteral<"question">, Type.TLiteral<"generic">]>>;
            }>>;
            /** The ONE mount condition that fired for this instance. */
            mountedBy: Type.TUnion<[Type.TLiteral<"hands">, Type.TLiteral<"backgroundTasks">, Type.TLiteral<"workflow">, Type.TLiteral<"delegation">, Type.TLiteral<"hostInternals">, Type.TLiteral<"peerLane">, Type.TLiteral<"scheduler">, Type.TLiteral<"memory">, Type.TLiteral<"scenario">, Type.TLiteral<"always">, Type.TLiteral<"optional">]>;
        }>>;
        /** sha256 prefix over the canonical COMPLETE rows — any axis / hint / contract / alias change moves it. */
        digest: Type.TString;
    }>;
    /** Three pairwise-disjoint name lists; a `changed` name's new row is in `roster`. */
    summary: Type.TObject<{
        added: Type.TArray<Type.TString>;
        removed: Type.TArray<Type.TString>;
        changed: Type.TArray<Type.TString>;
    }>;
}>;
export type ToolRosterDelta = Static<typeof ToolRosterDelta>;
/** The ONE name→row resolution every per-call reader shares (the call face, the park identity): the wire name first,
 *  then an alias — the same order the dispatcher resolves a model's call. */
export declare function rosterEntryNamed(roster: ToolRoster, toolName: string): ToolRosterEntry | undefined;
/**
 * The ONE tool-name canonicalization: the wire name of the row `name` resolves to on the roster ({@link rosterEntryNamed}
 * — the wire name first, then an alias, the dispatcher's order), or `name` itself when no row answers to it. The gate
 * reads a call's name through it before any policy runs, and a rule's tool name reaches a call exactly when it
 * canonicalizes to the same wire name (`ToolCallFace.names` is that set, minted here) — so a rule written against
 * an alias and one written against the wire name are one rule.
 */
export declare function rosterToolName(roster: ToolRoster | undefined, name: string): string;
export { ruleNamesOf } from "./tool-name-readings.js";
/** The reserved card a call owns, judged from its wire name alone — the ONE read of "is this the engine's question /
 *  plan tool": the card minted on a call's face, the park's question mark and the decide's answer binding all ask it. */
export declare function engineCardOf(call: {
    readonly toolName: string;
}): ReservedApprovalCard | undefined;
/** The approval card a call renders under: a reserved card only for the engine tool that owns it (whatever a row
 *  declares), otherwise the row's declared card, else `generic`. */
export declare function approvalCardOf(call: {
    readonly toolName: string;
}, declared: ToolApprovalCard | undefined): ToolApprovalCard;
/** The ask / gate member that carries a call's card: copied off the face the gate stamped, absent on a bare request. */
export declare function approvalCardMemberOf(call: {
    readonly face?: {
        readonly approvalCard?: ToolApprovalCard;
    } | undefined;
}): {
    approvalCard?: ToolApprovalCard;
};
/** design/388 B6 — the per-call face a gated request carries, read off a roster snapshot by name (aliases resolve).
 *  `names` leads with the name the face was minted under (the model's spelling at the gate), then the wire name and the
 *  other aliases — the ONE order of a call's names: a reader that must pick one of them by position (a `member` seat)
 *  picks the spelling first, as the same call was judged before name resolution. */
export declare function toolCallFaceOf(roster: ToolRoster | undefined, toolName: string): import("./tool-policy.js").ToolCallFace | undefined;
/** design/388 B18 — the identity members a park row carries, read off a roster snapshot by name; an empty object when
 *  the name is not on the snapshot (the row then reads pre-identity and the resume takes the name-only path). */
export declare function parkedToolIdentity(roster: ToolRoster | undefined, toolName: string): {
    capabilityId?: string;
    contractId?: string;
    shapeDigest?: string;
    implementationRevision?: string;
    rosterDigest?: string;
};
/** design/388 B6 × B18 — the FACE members a park row carries beside its identity: the display family, the declared
 *  path target and the names the parked call was judged under. `names` is copied from the face the gate stamped on the
 *  request (the model's spelling first — the row carries the judged fact, it is not re-derived); a request with no face
 *  takes the roster's names for its row. A recheck that runs before the leg's roster exists (the pre-CAS resume-edit
 *  re-adjudication) rebuilds the call face from the row through {@link parkedCallFaceOf}, so it judges the same object
 *  the live gate judged. An empty object when the name is not on the snapshot (the row then reads pre-face and the
 *  recheck falls to the catalog for the name). */
export declare function parkedToolFace(roster: ToolRoster | undefined, req: {
    readonly toolName: string;
    readonly face?: {
        readonly names?: readonly string[];
    } | undefined;
}): {
    family?: ToolFamily;
    pathTarget?: ToolRosterEntry["pathTarget"];
    names?: readonly string[];
};
/** The live face a resumed park row is re-judged under: minted under the row's recorded spelling (`names[0]`) when that
 *  spelling still resolves to the row's own tool on this roster, else under the row's wire name — a spelling that no
 *  longer resolves, or that another row now owns, never lends the row another tool's face. */
export declare function parkedRowLiveFace(roster: ToolRoster | undefined, row: {
    readonly toolName: string;
    readonly names?: readonly string[];
}): import("./tool-policy.js").ToolCallFace | undefined;
/** The call face a park row carries — present iff the row was minted with BOTH its face members and its four
 *  identity members (one mint writes all of them; a row missing any is pre-388 and yields undefined, never a
 *  partial face). This is the face every recheck of the row judges under, roster or no roster. */
export declare function parkedCallFaceOf(pending: {
    family?: ToolFamily;
    pathTarget?: ToolRosterPathTarget;
    names?: readonly string[];
    capabilityId?: string;
    contractId?: string;
    shapeDigest?: string;
    implementationRevision?: string;
}): import("./tool-policy.js").ToolCallFace | undefined;
/** The optional `face` seat of a ToolCallRequest: present iff a face was read (a bare request carries no key). */
export declare function callFaceSeat(face: import("./tool-policy.js").ToolCallFace | undefined): {
    face?: import("./tool-policy.js").ToolCallFace;
};
/** The four-tuple that decides "still the same tool" across a park (design/388 §2.5 boundary ②). */
export interface ToolIdentity {
    capabilityId: string;
    contractId: string;
    shapeDigest: string;
    implementationRevision: string;
}
export declare function toolIdentityOf(entry: ToolRosterEntry): ToolIdentity;
/** The engine-minted capability identity: a STRUCTURED tuple (never a joined string — `a:b`+`c` and `a`+`b:c`
 *  must not collide). Stable across legs for the same source/peer/name/contract. */
export declare function mintCapabilityId(t: {
    source: RosterSource;
    peer: string | null;
    name: string;
    contractId: string;
}): string;
export declare function rosterDigestOf(entries: readonly ToolRosterEntry[]): string;
/** The materialized schema's top-level properties, in declaration order. */
export declare function inputKeysOf(schema: TSchema | undefined): {
    keys: ToolRosterEntry["inputKeys"];
    scalar: Set<string>;
};
/** The roster's KEY bounds over a schema (design/388 B20): a problem sentence, or undefined when every top-level key fits.
 *  Shared by the caller declaration door (typed refusal) and the MCP intake (disclosed drop) — a key is never truncated. */
export declare function schemaKeyBoundProblem(schema: TSchema | undefined): string | undefined;
/** The identity members of one roster row the wire bounds hold, as a DECLARATION (the door) or a MINTED row hands them. */
export interface RosterBoundMembers {
    name: string;
    aliases?: readonly string[];
    /** An MCP/A2A mount's peer (the row's `origin.peer`) — a NAME on the roster, held to the wire name bound. */
    peer?: string;
    contractId?: string;
    implementationRevision?: string;
    modelGate?: string;
    cardId?: string;
}
/** The typed refusal a member over its bound mints — the door's two codes, and the mint's own for the members no
 *  declaration door names (`modelGate`, the derived `cardId`). Spelled out as literals (a consumer's tooling reads
 *  the words); each is a member of {@link ToolDeclarationCode}, which every mint below satisfies. */
export type RosterBoundCode = "config.tool_name_too_long" | "config.tool_contract_too_long" | "config.tool_roster_bound";
/**
 * design/388 B20 / #626 ① — the ONE bound judge over a row's identity members: a problem `{ code, message }`, or
 * undefined when every member fits. Read by the declaration door (a `TaskSpec.tools` entry, refused before session
 * acquire) and by the row mint (every source — an MCP/A2A peer, a definition that reached the mint by a route the
 * door does not cover — refused before the row exists). A member over its bound is NEVER truncated onto the row: a
 * truncated identity is a different identity (`judgeParkedToolIdentity` compares it across a park; the card
 * namespace door reads it), and the schema's own bounds would then describe a row the mint never made.
 */
export declare function rosterMemberBoundProblem(m: RosterBoundMembers): {
    code: RosterBoundCode;
    message: string;
} | undefined;
/**
 * The rule vocabulary of ONE mounted instance (design/388 §2.2 ③ / D-3): DERIVED = the scalar top-level
 * keys ∪ the path target's `param` + aliases; a declared `params` list can only NARROW it (a declared
 * name outside the derived set is dropped — the L6 gate names it for a built-in); `primaryParams` =
 * declared, else the path target's `param` + aliases.
 */
export declare function ruleFaceOfInstance(schema: TSchema | undefined, declared: ToolRuleFace | undefined, pathTarget: ToolPathTarget | undefined): {
    primaryParams: string[];
    params: string[];
};
/** The instance each NAME dispatches to when several are mounted under it: the LATER mount (the harness keeps the
 *  later one). The one selection — the roster's snapshot and every table keyed by a caller tool's name read it here. */
export declare function survivorsByName<T extends {
    readonly name: string;
}>(mounted: readonly T[]): Map<string, T>;
/** What a mount site knows that the instance does not: where the tool came from and which condition fired. */
export interface RosterMountMeta {
    source: RosterSource;
    mountedBy: ToolMountTag;
    /** Required for `mcp` / `a2a` / `external`; refused otherwise. */
    origin?: {
        peer: string;
        declaredBy?: "center" | "file" | "request";
    };
}
/** The face a mounted instance carries (forwarded by `defineTool`; read here by the same untyped-carry convention
 *  every other axis reader in the runner uses). */
export interface MountedToolFace {
    effect?: ToolEffect;
    egress?: true;
    irreversibility?: "never" | "maybe" | "always";
    reversibilityProbe?: unknown;
    contentOrigin?: ToolContentOrigin;
    offload?: boolean;
    offloadThresholdChars?: number;
    defer?: boolean;
    alwaysLoad?: boolean;
    mcpAlwaysLoad?: boolean;
    family?: ToolFamily;
    pathTarget?: ToolPathTarget;
    ruleFace?: ToolRuleFace;
    renderHints?: ToolRenderHints;
    compactable?: true;
    budgetExempt?: true;
    modelGate?: string;
}
export declare const faceOf: (t: AgentTool) => MountedToolFace;
/** The leg facts the snapshot reads beside the instances — the safety scan's folds and the per-task knobs. */
export interface RosterSnapshotFacts {
    /** The leg's by-name effect map (the builder is its mount-time writer; the protocol folds also write it). */
    effects: ReadonlyMap<string, ToolEffect>;
    egress: ReadonlySet<string>;
    irreversibilityTier: ReadonlyMap<string, "never" | "maybe" | "always">;
    reversibilityProbes: ReadonlyMap<string, unknown>;
    /** Names the defer classification ships as placeholders. */
    deferred: ReadonlySet<string>;
    /** `TaskSpec.memory.trustedTools` — the exemption channel for an undeclared content class. */
    trustedTools: ReadonlySet<string>;
}
export declare class RosterBuilder {
    #private;
    constructor(effects: Map<string, ToolEffect>);
    /** The mount array as a READ face. The order is the wire order. */
    get tools(): readonly AgentTool[];
    get length(): number;
    metaOf(tool: AgentTool): RosterMountMeta | undefined;
    /** Mount one instance at the tail. An engine-lane instance that DECLARES an effect writes it into the leg's effect
     *  map — the later mount under a name is the one the harness dispatches to (`snapshot`'s yield rule), so its
     *  declaration is the map's truth for that name; a pre-mount registration (the hand band, the plan pair, an
     *  MCP axis) stands only for names no mounted instance declares. The `scenario` lane never writes the map: its
     *  declarations were latched by the safety scan BEFORE any mount (on the kept instance of each name, on the
     *  synchronous doors+scan stretch — a microtask cannot flip them), so a scenario mount, kept or dropped, leaves
     *  the map as the scan made it; an engine lane's mount under that name still displaces it. */
    mount(tool: AgentTool, meta: RosterMountMeta): void;
    /** An ENGINE-INJECTED instance the harness list carries outside the mount array (the ToolSearch lane): a roster
     *  row — the model can call it — never a mount-array element (the disclosure lane owns that list and appends the
     *  instance itself). Its row follows the mount array's rows in the snapshot; the same admission rules apply. */
    mountEngineLane(tool: AgentTool, meta: RosterMountMeta): void;
    mountAll(tools: readonly AgentTool[], meta: RosterMountMeta): void;
    /** Remove every instance the predicate selects; returns them in mount order. */
    unmountWhere(pred: (tool: AgentTool, index: number) => boolean): AgentTool[];
    /** Swap the instance at `index` for another object standing for the SAME mount (a presentation re-render, a
     *  wrapper): the mount meta carries over. */
    replaceAt(index: number, tool: AgentTool): void;
    /**
     * Re-insert a NAME-PREFIX domain in place (the RefreshMcpTools seam): every instance whose name starts with
     * `prefix` is removed and `fresh` is spliced in at the domain's lowest former index (the wire prefix a
     * provider cache reads stays put); a domain that was not mounted appends at the tail.
     */
    replaceDomain(prefix: string, fresh: readonly AgentTool[], meta: RosterMountMeta): {
        anchor: number;
    };
    /** Mint the roster: one row per mounted NAME, in order. Two mounted instances under one name follow the
     *  harness's own yield (the LATER mount is the one the model dispatches to — design/141 Q4, the
     *  `auditToolCollisions` "yield" record): the roster carries the surviving instance's row at the
     *  yielded instance's position and never a row per object. */
    snapshot(facts: RosterSnapshotFacts): ToolRoster;
}
/**
 * The roster's one declaration rule on engine names: a row whose names (its wire name and the aliases that resolve to it,
 * {@link namesResolvingTo}) belong to TWO or more engine tools is refused — one tool answering as two engine tools would
 * have every per-call seat keyed on engine names choose between two definitions of the call. A row answering to one engine
 * tool under several of that tool's names, and an alias another row owns, are not counted twice. Undefined ⇒ none.
 */
export declare function rosterEngineNamesProblem(roster: ToolRoster): string | undefined;
/** Which source a `TaskSpec.tools` entry mounts as: a definition carrying a CORE contract is a built-in the host chose
 *  to mount; anything else is the caller's own tool. Identity follows the object, never the name. */
export declare function callerMountSource(tool: AgentTool): RosterSource;
/** The card namespace a roster row owns (design/388 §2.2 ④) — ONE mint, read by the row and by the prepare door that
 *  judges a caller's `renderHints.resultCards` against it: `builtin:<name>` for engine-owned definitions,
 *  `<mcp|a2a>:<peer>/<tool>` for protocol tools, `<caller|external>:<contractId>` for everything the caller mounts. */
export declare function rosterCardId(source: RosterSource, toolName: string, peer: string | null, protocolTool: string, contractId: string): string;
/** The card namespace a `TaskSpec.tools` entry will own once mounted — the same mint the row makes, so the prepare
 *  door and the roster row cannot disagree about which namespace a caller card must live under. */
export declare function callerCardIdOf(tool: Pick<AgentTool, "name" | "parameters">): string;
/** One row (design/388 §2.5). Every axis is read off the instance or the leg facts; nothing off a name table. */
export declare function mintRosterEntry(tool: AgentTool, meta: RosterMountMeta, facts: RosterSnapshotFacts): ToolRosterEntry;
/**
 * The run-time delta seat: armed with the leg's minted roster and a re-snapshot closure at prepare, it
 * re-mints the roster after every run-time roster change (the RefreshMcpTools seam), diffs it against the
 * last published one and hands the delta to the stream (`tool_roster_delta`). Deltas published before a
 * sink subscribes are buffered (bounded) and flushed at subscription, so the first consumer sees them.
 */
export declare class ToolRosterDeltaSeat {
    #private;
    arm(current: ToolRoster, snapshot: () => ToolRoster): void;
    /** The last minted roster (the prepared one until a run-time change re-mints it). */
    get current(): ToolRoster | undefined;
    /** Re-mint after a run-time change; publishes and returns the delta (undefined before arming). A
     *  byte-identical re-mint still publishes: the consumer's summary is empty and its digest unchanged. */
    republish(): ToolRosterDelta | undefined;
    /** Install the stream sink; anything published before is flushed in order. */
    subscribe(sink: (delta: ToolRosterDelta) => void): void;
    /** The leg ended: drop the sink so a late republish never reaches a closed stream (it buffers, bounded, unread). */
    unsubscribe(): void;
    /** Take the buffered deltas (a consumer that polls instead of subscribing). */
    drain(): ToolRosterDelta[];
}
/**
 * design/388 B15 — the rule-face resolver a leg hands the rule compiler: every roster row answers with its
 * derived vocabulary, the carried-but-non-scalar keys (so `Edit(edits:x)` reads `param_non_scalar`, not
 * `param_unknown`) and whether it names a path target; a name off the roster answers undefined.
 */
export declare function ruleFacesFromRoster(roster: ToolRoster): (toolName: string) => {
    primaryParams: readonly string[];
    params: readonly string[];
    nonScalar: readonly string[];
    pathTargeting: boolean;
} | undefined;
/** The delta between two snapshots (design/388 §2.5): the whole `next` roster plus the name summary. */
export declare function diffToolRoster(prev: ToolRoster, next: ToolRoster): ToolRosterDelta;
/**
 * The resume-side identity judgement (design/388 §2.5 boundary ②, B18/B19): a parked action carrying the
 * four identity members is redeemed only against a same-name row whose four members ALL match; a row
 * whose contract / shape / revision / source-peer moved is a replacement wearing the name, and the
 * resume refuses it (`resume.tool_contract_mismatch`, same family and disposition as
 * `resume.tool_unavailable`). A parked action minted BEFORE the identity members existed (all four absent)
 * follows the name-only path and is never widened by their absence.
 */
export declare function judgeParkedToolIdentity(pending: {
    capabilityId?: string;
    contractId?: string;
    shapeDigest?: string;
    implementationRevision?: string;
}, row: ToolRosterEntry | undefined): "match" | "mismatch" | "name_only" | "absent";
/** The card-namespace check a CALLER declaration must pass at prepare (design/388 §2.2 ④): a `resultCards`
 *  entry must live under the tool's own `cardId`; naming an engine card (`builtin:*`, or a bare engine card
 *  type) is refused. Returns the offending entry, or undefined. */
export declare function offendingResultCard(hints: ToolRenderHints | undefined, cardId: string, engineCards: ReadonlySet<string>): string | undefined;
