/**
 * toolExtras — agentfootprint's own tool DECLARATIONS, carried over MCP.
 *
 * A `Tool` is two different things at once. Half of it is EXECUTION — the
 * handler, the credential it needs, the human it wants to check in with. The
 * other half is DECLARATION — flat, inert facts about the tool that no code
 * runs and every consumer-side rail READS: where its arguments come from, what
 * kind of artifact its result is, who owns it, what class of answer it gives,
 * how big a result is too big.
 *
 * Over MCP only the execution half used to cross. A tool served by `mcpServe`
 * arrived at a client as a name, a description and an input schema, so every
 * rail that reads a declaration went quiet for it: the dangling-reference and
 * unsupported-argument checks never armed, placement minted
 * `tool-result/<name>` that no `wants` could spend, and the identity joins had
 * no subject. An MCP server could be somebody's whole tool catalogue and still
 * be a second-class citizen of every check this library ships.
 *
 * ── The carrier ─────────────────────────────────────────────────────────
 * MCP's own extensibility bag: `Tool._meta`, under ONE namespaced key
 * ({@link MCP_TOOL_EXTRAS_KEY}). `_meta` is declared on the spec's `Tool`
 * object (`@modelcontextprotocol/sdk` types it as
 * `z.record(z.string(), z.unknown()).optional()` on `ToolSchema`), so it
 * survives the SDK's own `tools/list` validation in both directions and needs
 * no new protocol, no side channel and no version negotiation. A server that
 * has never heard of agentfootprint sends no bag; a client that has never
 * heard of it ignores the key.
 *
 * ── What may travel, and the bar ────────────────────────────────────────
 * **A declaration a consumer-side check or rail reads; nothing that governs
 * execution.** Every field below passes it. `needs` (credentials), `checkIn`
 * (human consent) and the session hooks do NOT and never will: they govern how
 * a tool RUNS, and the tool runs on the server. Sending them would tell a
 * client to hold a gate that the only executor of the tool has already held,
 * or — worse — that nobody is holding at all. `mcpServe` already refuses to
 * serve a `checkIn` tool for exactly that reason; this list is the same law,
 * stated on the way out.
 *
 * ── The asymmetry that matters ──────────────────────────────────────────
 * SERVING validates nothing new: the tool was built by `defineTool`, which
 * already refused every malformed declaration at definition time.
 *
 * INGEST validates everything and THROWS NOTHING. A bag comes from a server
 * this process does not control, and one server's typo must not take down a
 * bulk register of forty tools. So each field is judged by the SAME rule
 * `defineTool` enforces (literally the same exported assert), and a field that
 * fails is warned about once — naming the server, the tool, the field and the
 * rule — and DROPPED. The tool still registers, without that one declaration.
 * That is the honest outcome: the rail it would have armed stays unarmed, and
 * the developer is told which rail and why.
 */
import { type Tool, type ToolOwner, type ToolResultCeiling, type ToolResultColumns } from '../tools/tools.js';
import type { ToolResultClass } from '../semantics/types.js';
import { type AskOrAssume, type ToolPeriod } from '../tools/declare.js';
import { type ToolScript } from '../tools/script.js';
import type { ToolSearch } from '../semantics/coverage/search/types.js';
import { type TimeContext } from '../time/wire.js';
/**
 * The single `_meta` key every agentfootprint declaration travels under.
 *
 * Namespaced so it can never collide with another vendor's `_meta` entry, and
 * a CONSTANT so there is exactly one spelling in the codebase — the
 * `branchSegment.ts` precedent upstream: one owner of the grammar, and nobody
 * else may write the string.
 */
export declare const MCP_TOOL_EXTRAS_KEY = "agentfootprint";
/**
 * The declarations that cross an MCP boundary — the plain-data half of a
 * `Tool`, in the shape the receiving side puts straight back onto a `Tool`.
 *
 * Every field is optional and ABSENT MEANS ABSENT: a tool that declares
 * nothing sends no bag at all, and a tool that declares two sends two keys,
 * never five with three empty placeholders. "Said nothing" and "said empty"
 * are different statements everywhere else in this library, and they are
 * different here.
 *
 * @see MCP_TOOL_EXTRAS_KEY for the `_meta` key it rides under.
 */
export interface McpToolExtras {
    /** Where this tool's arguments come from — see {@link Tool.argumentsFrom}.
     *  Arms the dangling-reference and unsupported-argument checks. */
    readonly argumentsFrom?: readonly string[];
    /** The artifact kind a PLACED result is minted under — see
     *  {@link Tool.resultKind}. What makes a placed result spendable by `wants`. */
    readonly resultKind?: string;
    /**
     * What this tool's ROWS contain (9.78.0) — see {@link Tool.resultColumns}.
     * Arms the write seam's `column-type-mismatch` and `missing-column` checks.
     *
     * It clears the bar this file states, and by the widest margin of the eight.
     * It is a flat, inert fact about the RESULT that a consumer-side check
     * reads; it governs nothing about how the tool runs, and the tool runs on
     * the server. It is also the field case for carrying declarations at all: a
     * remote catalogue of rowset tools is exactly where a numeric column
     * arriving as text goes unnoticed, because the consumer holding the chart
     * has no way to know what the producer meant. Leaving it behind would arm
     * the check for local tools and leave every MCP tool a second-class citizen
     * of it — the whole defect `toolExtras` was built to end.
     */
    readonly resultColumns?: ToolResultColumns;
    /** The identity edge integrity checks join on — see {@link Tool.owner}. */
    readonly owner?: ToolOwner;
    /** The declared class of this tool's results — see {@link Tool.resultClass}. */
    readonly resultClass?: ToolResultClass;
    /** The author's refusing ceiling on this tool's result — see
     *  {@link Tool.resultCeiling}. */
    readonly resultCeiling?: ToolResultCeiling;
    /** The named ingredient tools this tool is composed of (9.76.0) — see
     *  {@link Tool.composedOf}. Feeds the receiving agent's build-time drift
     *  gate. */
    readonly composedOf?: readonly string[];
    /** Whether this tool's procedure can raise an approval gate (9.76.0) — see
     *  {@link Tool.gates}. Read by composition-time checks that must keep a
     *  gating tool out of a fan-out branch. */
    readonly gates?: boolean;
    /**
     * The per-argument rules (the inputs layer, honesty layer 2) — see
     * {@link Tool.askOrAssume}. It passes this file's bar: the fill and the
     * batch ask happen in the CLIENT's own loop before the call
     * is sent — exactly as the client applies a served `resultCeiling` — and
     * nothing about how the server runs the tool changes. The FIRST extra
     * judged against the tool's schema, which is why the origin carries the
     * listed tool's `inputSchema`. A client that ignores `_meta` sees the
     * author's `required` and sends the value, or the server applies its own
     * default.
     */
    readonly askOrAssume?: AskOrAssume;
    /** Which arguments set the period the answer covers, the forms they take
     *  and the facts about the source — see {@link Tool.period}. Judged
     *  against the listed tool's own `inputSchema` and the KEPT `askOrAssume`
     *  (every argument a form names must carry a kept rule). A host tool
     *  written in another language declares the same object, field for field. */
    readonly period?: ToolPeriod;
    /**
     * What one call of this tool searches — see {@link Tool.search}. It passes
     * this file's bar: composition is a consumer-side reading of the call's
     * arguments and governs nothing about how the server runs the tool. Judged
     * against the listed tool's own `inputSchema` and the KEPT `period`. A kept
     * remote declaration composes rows marked `composed: 'remote'`, which
     * establish nothing: the server's words are untrusted.
     */
    readonly search?: ToolSearch;
    /**
     * This tool RUNS a program, carried by its one string argument `argument`
     * — see {@link Tool.script}. It passes this file's bar: a consumer-side
     * record reads it (which program a call submitted, matched against what the
     * answer shows) and it governs nothing about how the server runs the tool.
     * Judged against the listed tool's own `inputSchema`.
     */
    readonly script?: ToolScript;
}
/**
 * The `_meta` bag a `tools/call` request carries for a call handed
 * `ctx.time` (the time layer, `time/wire.ts` · `TimeContext`): the
 * same object, under the one namespaced key — so a host tool in another
 * process can declare the `period.queried` its read covered without parsing
 * its own argument.
 */
export declare function callMetaOf(time: TimeContext): Readonly<Record<string, unknown>>;
/**
 * The call's time a `tools/call` request carried in its `_meta` bag, read —
 * or `undefined` when it carried none, or one this runtime cannot read (a
 * different version, a malformed field): never repaired, never guessed. What
 * `mcpServe` hands a served tool as `ctx.time`.
 */
export declare function callTimeOf(meta: unknown): TimeContext | undefined;
/**
 * The declarations on `tool`, ready to be written into an MCP `_meta` bag —
 * or `undefined` when the tool declares none, so `mcpServe` can leave `_meta`
 * off the listing entirely rather than sending an empty object.
 *
 * Copied verbatim, never inferred or defaulted. This is the SERVE side, and
 * the values were already vetted by `defineTool`.
 */
export declare function toolExtrasOf(tool: Tool): McpToolExtras | undefined;
/** Where a rejected declaration came from, for the warning that names it. */
export interface McpToolExtrasOrigin {
    /** The client's logical name — `mcpClient({ name })`. */
    readonly server: string;
    /** The tool the bag was attached to. */
    readonly tool: string;
    /**
     * The listed tool's own `inputSchema` — what `askOrAssume` and `period` are
     * judged against (each ruled property by its OWN schema). Absent → those
     * two fields are judged against an empty schema, so every rule is dropped
     * with a warning rather than trusted unjudged.
     */
    readonly inputSchema?: Readonly<Record<string, unknown>>;
}
/**
 * Read an MCP `Tool._meta` bag into declarations a `Tool` can carry.
 *
 * **Never throws.** Everything here is somebody else's data:
 *
 *   - no `_meta`, no `agentfootprint` key, or a non-object under it → `{}`,
 *     and the ingest is byte-identical to every release before this existed;
 *   - a field the receiving side does not know → ignored in silence (a NEWER
 *     server talking to an OLDER client is not an error, and warning about it
 *     would make every upgrade noisy at the wrong end);
 *   - a field this library DOES know but cannot honour → warned once and
 *     dropped, and the rest of the bag still lands.
 *
 * The rule each field is judged by is the exported assert `defineTool` itself
 * calls, so a declaration that would have been refused at definition time is
 * refused here too, with the same sentence.
 */
export declare function readToolExtras(meta: unknown, origin: McpToolExtrasOrigin): McpToolExtras;
/**
 * Forget every warning issued so far.
 * @internal test seam — the ledger is process-wide and warn-ONCE, so a test
 *   proving the warning fires must be able to start from silence.
 */
export declare function _resetToolExtrasWarnings(): void;
