/**
 * semantics/described — `describedResult()`, the declaration door spelled the
 * way code is written.
 *
 * Pattern: one core, one authoring door (`envelope.ts` · `mintSemantics`). This file
 *          is the camelCase door: it says how its author spells the
 *          declaration and respells each object to the wire. It judges
 *          nothing itself — every rule lives in the core, once.
 * Role:    lib/ layer, pure.
 * Emits:   N/A (the caller emits `agentfootprint.tools.semantics_declared`).
 *
 * ## One authoring spelling, one unchanged wire
 *
 * `semantic()` copied the wire's snake_case names into its declaration
 * (`measured_at`, `is_counter`, `filter_note`) beside camelCase ones
 * (`notChecked`, `cannotCover`), so an author wrote two spellings in one
 * object — and "semantic" already means vector retrieval everywhere else in
 * this library. `describedResult()` takes the same fields in camelCase and
 * mints the same wire, byte for byte. The wire does not change: the model and
 * any foreign process keep reading snake_case.
 *
 * The authoring door takes ONE spelling and refuses snake_case, quoting the key its
 * author wrote and naming the one meant (`provenance.measured_at` → "did you
 * mean `measuredAt`?"). A migration that swaps only the function name then
 * fails loudly at the line that needs the new spelling, instead of silently
 * minting without it. The declaration never accepts both spellings in one object.
 */
import { type SemanticIssue } from './envelope.js';
import type { DescribedResultDeclaration, SemanticProvenance, ToolSemantics } from './types.js';
/** A provenance declaration as an author writes it (camelCase) — and as the record keeps it. */
export type DeclaredProvenance = NonNullable<DescribedResultDeclaration['provenance']>;
/**
 * Mint an author's (camelCase) `provenance` into the wire's spelling by THIS
 * door's rules — `absent()` asks it (honesty step 7b), so an absence says its
 * source and time in the shape, the spelling and the rule set a described
 * result does: `measuredAt` and `source` required, `ageSeconds` a finite
 * number ≥ 0, `sourceExportDate` a non-empty string, a snake_case key refused
 * naming the camelCase one. THROWS the refusal (`refused: …`) at the line the
 * author wrote. A fresh object, keys in the author's order.
 */
export declare function mintProvenance(declared: unknown): SemanticProvenance;
/** What a recognizer read off an envelope's `provenance`. */
export interface ProvenanceReading {
    /** The record's camelCase form — present when the envelope declared a well-formed one. */
    readonly provenance?: DeclaredProvenance;
    /** The first fault, when it declared one the record cannot carry. */
    readonly problem?: SemanticIssue;
}
/**
 * Read a WIRE provenance (an absence minted anywhere — a Python helper, an
 * older process) into the record's camelCase form, by the same rule set —
 * never repaired. `{}` when none is declared (`undefined` or `null`).
 */
export declare function readProvenance(wire: unknown): ProvenanceReading;
/**
 * Return rows, a series or relationships from a system of record — WITH the
 * caveats that make them honest — in a shape the framework recognizes, the
 * record keeps whole, and a build gate can refuse.
 *
 * **Where it lives.** It is the tool's RESPONSE: `execute` returns it, and
 * nothing is added to the system prompt or the tool's schema. The model reads
 * a compact projection ({@link semanticsForModel}: the data, `grain`,
 * `provenance`, the `not_covered` lines composed from `coverage`, a non-null
 * `clarify` and a static note) — never the `checked` list, the `render` hints
 * or the marker. The run record keeps the FULL envelope
 * (`agentfootprint.tools.semantics_declared`), even when the result is over
 * the tool's `resultCeiling` and refused. A declared `coverage` also flows
 * through the channel `coverage()` uses, which is the only part that can reach
 * the final answer (`.limitsTravelWithTheAnswer()`).
 *
 * **Values from the data.** `provenance.measuredAt` is when the WORLD was
 * measured, taken from the data — the export's time, the moment of a live
 * read, the newest sample of a series, the end of a window — never typed in.
 * It is never parsed: the library passes your words through.
 *
 * **The period** (honesty step 7b). `period: { queried, held, readAt? }` says
 * what time the READ covered — the instants it asked for, and what the store
 * holds (or `'unknown'`) — as ISO 8601 instants with a zone. The model reads it
 * as declared; the results layer compares the instants and files its verdict
 * (covered · partly held · not held · unknown). A malformed period is refused
 * here.
 *
 * Refuses (throws, at the call site — the `absent()` law) any declaration
 * this vocabulary cannot honor: series without `grain`, series or facts
 * without `provenance.measuredAt` and `provenance.source`, a counter-looking
 * aggregation with `isCounter` unstated, and every malformed shape. Each
 * refusal starts `refused: `, names the field as you spelled it, and — inside
 * `execute` — is the call's error result, which the model reads in place of
 * the data; the run continues. A snake_case key (`measured_at`,
 * `not_checked`) is refused, naming the camelCase one.
 *
 * Use `absent()` when nothing matched and `coverage()` for
 * any other value that has limits; never wrap one helper's result in another.
 *
 * @example rows from a nightly export — the time comes from the export
 * ```ts
 * const exportTime = snapshot.exportedAt; // when the WORLD was measured
 * return describedResult({
 *   facts: rows.map((r) => ({ entity: r.vm, datastore: r.datastore, size_tb: r.sizeTb })),
 *   provenance: { measuredAt: exportTime, source: 'RVTools export' },
 *   coverage: {
 *     checked: [`every VM in the RVTools export of ${exportTime}`],
 *     cannotCover: [{ what: 'hosts that are not VMware', why: 'RVTools sees VMware only' }],
 *   },
 * });
 * ```
 *
 * @example a series — `measuredAt` is the newest sample
 * ```ts
 * const newest = rows.reduce((a, b) => (a.time > b.time ? a : b)).time;
 * return describedResult({
 *   series: rows.map((r) => ({ t: r.time, entity: r.port, metric: 'avg_iops', value: r.iops })),
 *   grain: { interval: '30m', aggregation: 'avg', isCounter: false },
 *   provenance: { measuredAt: newest, source: 'InfluxDB SwitchPortStats' },
 * });
 * ```
 */
export declare function describedResult(decl: DescribedResultDeclaration): ToolSemantics;
