/**
 * semantics/envelope — minting, recognizing and projecting the semantic
 * tool-result envelope (9.53.0).
 *
 * Pattern: minted by a helper, RECOGNIZED by the framework (the `absent()` /
 *          tool-effects precedent). A return shape the framework does not
 *          understand is a convention, and a convention cannot ride the
 *          record, feed a UI, or be refused by a build gate.
 * Role:    lib/ layer, pure. The dispatch loop calls `readSemantics` at the
 *          execute boundary; `describedResult()` is what a tool author writes;
 *          `checkSemantics` (check.ts) judges the same shapes offline.
 * Emits:   N/A (the caller emits `agentfootprint.tools.semantics_declared`).
 *
 * ## Two views of one envelope — the design decision, stated
 *
 * The MODEL reads a compact, rendering-free projection
 * ({@link semanticsForModel}): the data (`series`/`facts`/`edges`), the
 * caveats that must travel with it (`grain`, `provenance`), the composed
 * `not_covered` prose, a non-null `clarify`, and the static note. Dropped
 * from the model's view: the `af_semantics` marker (machine-only), `render`
 * (a UI hint — the tool never renders, and a model parroting rendering
 * directives is noise), the three-list `coverage` detail (it rides the
 * coverage channel and the record; the model reads the composed
 * `not_covered` lines instead), and a `clarify: null` (a stated non-question
 * is a fact for the record, not something the model acts on).
 *
 * The RECORD gets everything: the full envelope — render, coverage,
 * marker and all — lands on the `tools.semantics_declared` event BEFORE the
 * result ceiling is measured, so grain and provenance survive to recordings
 * and UIs even when the content itself is refused as oversized. The
 * `coverage` field is additionally declared through the SAME channel the
 * `coverage()` primitive uses (`tools.coverage_declared`, tracked state, the
 * final-answer limits block) — absorbed, never duplicated.
 *
 * ## One rule set for authoring and recognition
 *
 * The mint refuses a declaration this vocabulary cannot honor at the
 * CALL SITE (the `absent()` law) — so a minted envelope is honest by
 * construction: series carry their grain, data carries its provenance,
 * counter-looking aggregations state `is_counter`. `semanticIssues()` judges
 * the RENDERED shape — the same rules over a value somebody may have built
 * by hand — and is what recognition and the `check:semantics` gate both
 * stand on. Recognition is STRICT (the zero-cost guarantee): a marker-
 * bearing value with any issue is NOT recognized — it keeps its bytes on
 * the data path (dev-warned, and named field-by-field by the gate), because
 * this library does not half-apply a shape it cannot fully honor.
 *
 * ## One authoring door, one unchanged wire
 *
 * `describedResult()` declares camelCase names, then `mintSemantics` applies
 * the same rule set used to recognize stored snake_case envelopes. Validation
 * and record reading keep one owner; old wire records never need an adapter.
 */
import { type DeclaredPeriod } from './coverage/period.js';
import type { Coverage } from './coverage/types.js';
import { type DescribedResultDeclaration, type SemanticCoverage, type ToolSemantics } from './types.js';
/** The codes an envelope can be faulted with — shared by recognition (any
 *  issue ⇒ not recognized) and the `check:semantics` gate (issues become
 *  findings under these same names). */
export type SemanticIssueCode = 'malformed-semantics' | 'series-without-grain' | 'counter-aggregation-unstated' | 'data-without-provenance';
/** One fault, naming the field so a refusal can teach and a gate can point. */
export interface SemanticIssue {
    readonly code: SemanticIssueCode;
    /** The offending / missing field, dot-pathed ('grain.is_counter'). */
    readonly field: string;
    readonly message: string;
}
/** Whole-token match against {@link COUNTER_AGGREGATION_WORDS}, singular or
 *  plural, case-insensitive — 'sum' and 'Counts' look like counters,
 *  'summary' does not. */
export declare function isCounterLookingAggregation(aggregation: string): boolean;
/**
 * The keys a {@link SemanticClarify} has — spelled the same in declarations
 * and recorded envelopes — tied to the type in BOTH directions.
 */
export declare const CLARIFY_DECLARATION_KEYS: readonly string[];
/**
 * The six fields whose WIRE name is snake_case — the only names a declaration
 * door may spell differently. Everything else (`interval`, `source`,
 * `default`, the data rows, the eight top-level fields) is one word on both
 * sides.
 */
export type SpelledField = 'is_counter' | 'measured_at' | 'age_seconds' | 'source_export_date' | 'filter_note' | 'chart_hint';
/** How one door's author spells each {@link SpelledField}. */
export type Spelling = Readonly<Record<SpelledField, string>>;
/** The wire's own spelling — what `semanticIssues`, recognition, the gate
 *  speak. */
export declare const WIRE_SPELLING: Spelling;
/** The objects inside a declaration whose keys a door checks by name. */
export type DeclaredObject = 'grain' | 'provenance' | 'coverage' | 'clarify' | 'render';
/** The objects inside a declaration a door copies into their wire spelling. */
export type RespelledObject = 'grain' | 'provenance' | 'render';
/**
 * How the authoring door spells its declaration and translates it to the
 * wire. The rule set is shared with record recognition; only field spelling
 * differs between authoring refusals and stored-record findings.
 */
export interface DeclarationDoor {
    /** The helper's name, for the one refusal that names the call itself. */
    readonly name: string;
    /** The top-level keys a declaration may carry. */
    readonly declarationKeys: readonly string[];
    /** The keys that would hand-write the DERIVED `not_covered` prose list. */
    readonly derivedKeys: readonly string[];
    /** Each object a declaration may carry, with the keys it has in this
     *  door's spelling — refused BEFORE anything is copied. */
    readonly objectKeys: ReadonlyArray<readonly [field: DeclaredObject, known: readonly string[]]>;
    /** Copy one declared object into the wire's spelling, keeping key order.
     *  What it does with a value that is not a plain object is the door's own
     *  call: the rule set names whatever reaches the candidate. */
    readonly toWire: (field: RespelledObject, value: unknown) => unknown;
    /** How this door's author spells the six snake_case wire fields. */
    readonly spelling: Spelling;
}
/** Compose the `not_covered` prose lines FROM coverage — the one derivation,
 *  used by the mint and by the drift check, so the two can never disagree. */
export declare function composeNotCovered(coverage: SemanticCoverage): readonly string[];
/**
 * THE provenance rule — one present `provenance` object, in the wire's
 * spelling, judged; every fault, each naming its field the way `s` spells it.
 * `issuesIn` asks it for a described result, and `coverage/absent.ts` asks it
 * for an absence's `provenance` (honesty step 7b), so the two doors cannot
 * disagree about what a well-formed source and time is: `measured_at` and
 * `source` required, `age_seconds` a finite number ≥ 0, `source_export_date`
 * a non-empty string, no other key.
 */
export declare function provenanceIssues(provenance: unknown, s: Spelling): SemanticIssue[];
/**
 * Judge one RENDERED envelope shape against the whole rule set. Empty = a
 * well-formed envelope this library can honor. Non-empty = the faults, each
 * naming its field.
 *
 * Called with values that carry the marker; on anything else it reports the
 * missing marker rather than guessing.
 */
export declare function semanticIssues(value: unknown): readonly SemanticIssue[];
/**
 * The ONE mint behind `describedResult()`. Refuses (throws, at the call site — the `absent()` law) any
 * declaration this vocabulary cannot honor, in the door's own words; returns
 * the rendered envelope otherwise.
 *
 * In order: the declaration must be an object; a hand-written `not_covered`
 * is refused as derived; every key the declaration and its objects carry must
 * be one the door reads (a casing slip names the spelling meant); coverage is
 * normalized; the candidate is built in the WIRE spelling; and the whole rule
 * set judges it, naming each field as the door's author spelled it.
 */
export declare function mintSemantics(decl: DescribedResultDeclaration, door: DeclarationDoor): ToolSemantics;
/**
 * Recognize (or decline to recognize) a value as a semantic envelope —
 * STRICT, and the strictness is the zero-cost guarantee. Only a plain object
 * whose `af_semantics` is exactly `true` AND that passes the whole rule set
 * qualifies; every other value any tool has ever returned takes the path it
 * always took, byte for byte.
 *
 * `undefined` means "not an envelope this library can honor" — a marker-
 * bearing value with faults stays DATA (never half-applied); the dispatch
 * loop dev-warns it and `check:semantics` names every fault.
 */
export declare function readSemantics(value: unknown): ToolSemantics | undefined;
/**
 * Name what is wrong with a value that CARRIES the marker but was not
 * recognized. `undefined` for values without the marker (they are data, not
 * near-misses) and for well-formed envelopes. Diagnosis only — never changes
 * what any value does.
 */
export declare function explainSemantics(value: unknown): readonly SemanticIssue[] | undefined;
/**
 * The MODEL's view of one recognized envelope — compact and rendering-free.
 *
 * Keeps: the data (`series`/`facts`/`edges`), the caveats that must travel
 * with it (`grain`, `provenance`), the composed `not_covered` prose, a
 * non-null `clarify`, and the static note. Drops: the marker, `render`
 * (UI hint), the three-list `coverage` detail (rides the coverage channel
 * and the record), and a `clarify: null`. Shallow-copied so the history
 * entry is not the object the tool still holds.
 *
 * The period is served as the tool declared it — plus, when the store did not
 * hold all of the time the read asked about, the verdict word inside it and
 * that word's one clause after the note (`coverage/period.ts` ·
 * `servedPeriod`; honesty step 7b, bench round 1). A `covered` period and an
 * envelope with none are served byte for byte as before.
 */
export declare function semanticsForModel(sem: ToolSemantics): Record<string, unknown>;
/**
 * The period a RECOGNIZED envelope declared, in the record's camelCase form
 * (honesty step 7b) — `undefined` when it declared none. Recognition already
 * held the period to the rule set (a fault keeps the whole envelope data), so
 * this is a read, never a judgement.
 */
export declare function periodOfSemantics(sem: ToolSemantics): DeclaredPeriod | undefined;
/** The envelope's coverage in the normalized three-list shape the coverage
 *  machinery reads — how `readCoverageResult` absorbs a semantic envelope's
 *  boundary into the one coverage channel. */
export declare function coverageOfSemantics(sem: ToolSemantics): Coverage;
//# sourceMappingURL=envelope.d.ts.map