/** * Tool Semantic Registry — PRI-634-F Phase 1 (Tool Semantic Closure) * * PURPOSE: One authoritative mapping from raw tool names to the closed * CanonicalKind enum, so replay and production resolve identical tool * semantics for the same raw name. * * OWNERSHIP (SPEC §5, mirroring the anti-drift note in rule-context-v2.ts): * - core owns the CLOSED CanonicalKind enum + the host-neutral baseline * table (generic LLM vocabulary names, no host-specific tools); * - each host owns its raw tool name list and declares mappings that are * layered on top of the baseline (host wins on conflict); * - core never grows the baseline with host tool names. * * Pure logic — zero I/O. Runtime Contract: mappings arrive as untrusted * `unknown` at the public builder boundary and are validated structurally * (rc-1, rc-2, rc-4, rc-5) before use. */ import type { CanonicalKind } from './rule-context-v2.js'; export type { CanonicalKind } from './rule-context-v2.js'; export interface ToolSemanticMappingV1 { readonly rawToolName: string; readonly canonicalKind: CanonicalKind; } /** Resolved registry: closed lookup surface shared by replay and production. */ export interface ToolSemanticRegistry { readonly version: 1; /** * Explicit lookup. Returns `null` when the raw name has no mapping in * baseline + host layers — classification contexts use this to distinguish * "known kind" from "unknown". */ lookup(rawToolName: string): CanonicalKind | null; /** * Runtime lookup with graceful fallback: unknown names resolve to 'other' * (same semantics as canonicalizeToolKind — production evaluation must * never throw on an unmapped tool name). */ resolve(rawToolName: string): CanonicalKind; /** * PRI-634-F R2 (review P1): SEMANTIC RESOLVABILITY IS NOT HOST EXISTENCE. * True iff the raw name is declared by the HOST layer — i.e. the host * actually dispatches this tool name AND routes it to the RuleHost gate. * Core-baseline membership (generic LLM vocabulary like `execute_command`, * or read/search names the OpenClaw hook never routes) never counts as * existence evidence: a rule matching such a name passes replay against * fictional inputs while never firing in production — exactly the failure * class PRI-634-F exists to eliminate. */ hasHostTool(rawToolName: string): boolean; /** True iff this registry carries a host-declared layer at all. */ readonly hasHostLayer: boolean; /** * PRI-741: read-only projection of the HOST layer declarations (raw name → * canonicalKind), for prompt DTOs that must teach generators the real host * dispatch surface. Empty for a baseline-only registry. This is a view of * the declaration this registry was built from — never a writable surface. */ hostMappings(): readonly ToolSemanticMappingV1[]; } export interface ToolSemanticMappingValidationResult { readonly valid: boolean; readonly errors: readonly string[]; } /** * Validate untrusted host mappings (rc-1: unknown until validated; rc-4: every * element checked, not just "is array"; rc-5: Object.hasOwn over `in`). */ export declare function validateToolSemanticMappings(raw: unknown): ToolSemanticMappingValidationResult; /** * Build the effective registry: host mappings validated then layered over the * host-neutral core baseline (host wins on conflict). Returns a discriminated * result so an invalid host declaration fails loud at construction (rc-3) * instead of silently degrading to baseline. */ export declare function buildToolSemanticRegistry(hostMappings?: readonly ToolSemanticMappingV1[]): { ok: true; registry: ToolSemanticRegistry; } | { ok: false; errors: readonly string[]; }; //# sourceMappingURL=tool-semantic-registry.d.ts.map