/**
 * The one reading of a {@link ToolSpec} object. A spec is the caller's own mutable object graph, and the factory and the
 * run's roster snapshot both turn it into something that outlives the moment it was read; each takes its copy through
 * here, so a member is read once, by name, through an ordinary property read (an inherited, non-enumerable or
 * Proxy-answered declaration included — how every phase reads a declaration), and the copy holds no object the caller can
 * reach: declaration data (lists, schemas, faces, hints) is copied level by level — own string AND symbol keys, so a
 * TypeBox schema keeps its kind marks — and frozen, and the only values kept by reference are the functions a ToolSpec
 * declares as functions ({@link FUNCTION_MEMBERS}).
 *
 * A declaration the copy cannot take is refused, naming the member path, with the declaration door's code: a function inside
 * data, an object with a prototype (a class instance, a Date, a Map), an accessor, a graph past the node or depth budget.
 * A tool-name list is the one lenient place, and only at the places its judge reads one ({@link NAME_LIST_MEMBERS},
 * {@link FACE_LIST_KEYS}): it is taken through the judge's own snapshot ({@link snapshotToolNameList}), so a container that
 * cannot be read becomes the judge's failure marker and an entry the copy cannot take stands in as an inert value of the same
 * JS type — the judge refuses either with the sentence it always had, without the caller's object ever being on the face.
 */
import type { ToolSpec } from "./tool-spec.js";
/** Every {@link ToolSpec} member, by name — the type's own key set, fenced both ways (a member added to `ToolSpec` and not
 *  listed here, or a name here that `ToolSpec` does not declare, is a compile error). */
export declare const TOOL_SPEC_MEMBERS: readonly string[];
/** One copy's ledger: the nodes charged so far (a value is a node; a container is charged for all its slots / keys when it is
 *  entered, before anything is allocated, and its children are not charged again), the source objects already copied (a graph
 *  that shares a sub-node copies it once and charges it once — strict and lenient copies kept apart) and the sources being
 *  copied now (a cycle is refused). */
export interface CopyState {
    nodes: number;
    readonly seen: WeakMap<object, object>;
    readonly seenLenient: WeakMap<object, object>;
    readonly inflight: Set<object>;
}
export declare const newCopyState: () => CopyState;
/** One member's value, as the face and the factory's copy hold it. `state` is the ledger of the whole spec / entry. */
export declare function frozenMember(name: string, value: unknown, state: CopyState): unknown;
/** A value under a key that is no ToolSpec member (a contract symbol, a decoration): the engine reads no declaration off it, so
 *  it is carried when it is plain data and left off the face when it is not. */
export declare function frozenExtra(key: string, value: unknown, state: CopyState): {
    kept: true;
    value: unknown;
} | {
    kept: false;
};
/** A spec as it stands now: a frozen object holding each {@link TOOL_SPEC_MEMBERS} member as read once (a member the spec does
 *  not answer for stays absent). The caller keeping its own object and changing it afterwards — a member, or anything inside a
 *  list or a schema — changes nothing here. */
export declare function frozenToolSpec<T extends ToolSpec>(spec: T): Readonly<T>;
