/**
 * coverage/period — the ONE period shape a result declares, the ONE rule set
 * every door asks, and the ONE verdict.
 *
 * Pattern: one rule set, every door (the `items.ts` law for `short` and
 *          `kind`): the three mints — `absent()`, `coverage()`,
 *          `describedResult()` — REFUSE a malformed period at the line the
 *          author wrote, and the recognizers READ a period an envelope minted
 *          elsewhere (a Python helper, an older or newer process) without
 *          repairing it. Both ask {@link periodProblem}, so a mint and a read
 *          cannot disagree about what a well-formed period is.
 * Role:    core/ layer leaf of the result doors (honesty layer 3). Imports only
 *          `refusal.ts`, the dev-mode flag and the time layer's one instant
 *          parser (`time/instant.ts` · `instantOf`, lenient profile) and its
 *          person-facing renderer (`time/present.ts`). The results layer
 *          (`../../core/agent/results/subflow.ts`) files one verdict per call from
 *          {@link periodVerdict}; the limits block prints one line per
 *          declaring call from {@link periodLine}.
 * Emits:   N/A.
 *
 * ## The shape — anchored on the READ
 *
 * ```ts
 * period: {
 *   queried: { from: '2026-09-26T09:00:00Z', to: '2026-09-26T10:00:00Z' }, // what the read asked for
 *   held: { from: '2026-08-27T02:00:00Z', to: '2026-09-26T02:00:00Z' },    // what the store holds — or 'unknown'
 *   readAt: '2026-09-26T10:00:03Z',                                         // when the read ran (optional)
 * }
 * // on the wire: "period": { "queried": {…}, "held": {…} | "unknown", "read_at"? }
 * ```
 *
 * Every value is an ISO 8601 instant WITH a zone (`Z` or `±HH:MM`) — the
 * library compares instants, and an instant without a zone is ambiguous, so it
 * is refused rather than guessed. `held: 'unknown'` is the store saying out
 * loud that it cannot vouch for what it holds. Nothing here ever parses a
 * duration: the library compares instants the tool declared and never reads
 * "2h" (the inputs layer's `ToolPeriod` says which ARGUMENT set the period;
 * this shape says what the READ covered).
 *
 * ## Why not the word `window`, and why not a coverage item
 *
 * `window` names the context window (`core/agent/window/`, `.window()`). A
 * coverage item's `kind` is a closed, record-only word: it cannot hold two
 * instants to compare.
 */
import type { BoundPresentation } from '../../time/present.js';
import { type PeriodDiffers, type SourceClock } from '../../time/checkRecord.js';
/**
 * The period a result declares — what its READ covered — in the camelCase
 * spelling an author writes on `absent()`, `coverage()` and
 * `describedResult()`, and the record keeps (the `coverageDeclared` row, the
 * `tools.absent` / `tools.coverage_declared` events). The wire spells it
 * snake_case (`read_at`).
 *
 * @example
 * ```ts
 * absent({
 *   what: 'failed backup runs for host-103',
 *   checked: ['every job in the 02:00 export'],
 *   period: {
 *     queried: { from: '2026-09-26T09:00:00Z', to: '2026-09-26T10:00:00Z' },
 *     held: { from: '2026-08-27T02:00:00Z', to: '2026-09-26T02:00:00Z' },
 *   },
 * });
 * ```
 */
export interface DeclaredPeriod {
    /** The instants of the READ that produced this result — not of "this call".
     *  ISO 8601 instants WITH a zone; `from` is not after `to`. */
    readonly queried: {
        readonly from: string;
        readonly to: string;
    };
    /** What the store holds at the time of the read — the same shape — or
     *  `'unknown'`, said out loud when the tool cannot vouch for it. */
    readonly held: {
        readonly from: string;
        readonly to: string;
    } | 'unknown';
    /** When the read ran — a cached answer is served minutes after the read it
     *  describes. An ISO 8601 instant with a zone. */
    readonly readAt?: string;
}
/**
 * {@link DeclaredPeriod} as the wire spells it — `read_at` is the one key that
 * differs. What a model reads inside `af_absent`, `af_coverage` and
 * `af_semantics`, and what a foreign minter writes (`canonical-notes.json`
 * publishes every key, {@link PERIOD_WIRE}).
 *
 * @inline
 */
export interface PeriodOnWire {
    readonly queried: {
        readonly from: string;
        readonly to: string;
    };
    readonly held: {
        readonly from: string;
        readonly to: string;
    } | 'unknown';
    readonly read_at?: string;
}
/**
 * The period's wire spelling as DATA — every reserved key and the one literal
 * (`'unknown'`) — so a tool written in another language mints it byte for
 * byte. `canonical-notes.json` publishes it, generated from this constant
 * (`scripts/gen-canonical-notes.mjs`): the JSON cannot disagree with the code.
 *
 * @example
 * ```ts
 * PERIOD_WIRE.readAt; // 'read_at' — the one key whose wire spelling differs
 * ```
 */
export declare const PERIOD_WIRE: Readonly<{
    /** The key a period sits under on `af_absent`, `af_coverage` and `af_semantics`. */
    readonly key: "period";
    readonly queried: "queried";
    readonly held: "held";
    readonly from: "from";
    readonly to: "to";
    readonly readAt: "read_at";
    /** The literal `held` carries when the store cannot vouch for what it holds. */
    readonly heldUnknown: "unknown";
}>;
/**
 * How far a result's READ covered what it asked for — one pure rule over the
 * instants the tool declared (bounds are inclusive):
 *
 * - `covered` — the store holds every instant the read asked for;
 * - `partly-held` — it holds some of them;
 * - `not-held` — it holds none of them;
 * - `unknown` — the tool said it cannot vouch for what the store holds.
 *
 * @inline
 */
export type PeriodVerdict = 'covered' | 'partly-held' | 'not-held' | 'unknown';
/** Which door's words a problem is named in: the author's (camelCase) or the wire's. */
export type KeySpelling = 'camel' | 'wire';
/** One fault in a period, naming its field the way the reader spelled it. */
export interface PeriodProblem {
    /** Dot-pathed, from `period` down (`period.queried.from`, `period.readAt`). */
    readonly field: string;
    readonly message: string;
}
/**
 * THE rule set: the first fault in a period, or `undefined` when it is well
 * formed — asked by every mint (which refuses it) and every recognizer (which
 * drops it from the record and serves the envelope as the tool wrote it).
 *
 * In order: a plain object; no key it does not have (a spelling slip names the
 * key meant — `read_at` at a camelCase door names `readAt`); `queried` a
 * `{ from, to }` span of instants with `from` not after `to`; `held` the
 * literal `'unknown'` or a span by the same rule; `readAt` an instant.
 *
 * @example
 * ```ts
 * periodProblem({ queried: { from: 'yesterday', to: '2026-09-26T10:00:00Z' }, held: 'unknown' }, 'camel');
 * // → { field: 'period.queried.from', message: '`period.queried.from` must be an ISO 8601 instant with a zone — …' }
 * ```
 */
export declare function periodProblem(value: unknown, spelling: KeySpelling): PeriodProblem | undefined;
/**
 * Mint the wire form from an author's (camelCase) declaration — THROWS a
 * refusal (`refused: …`) on the first fault, at the line the author wrote (the
 * `absent()` law). `undefined` or `null` → `undefined`: not declared. A fresh
 * object, keys in wire order; nothing of the author's is held.
 */
export declare function mintPeriod(declared: unknown): PeriodOnWire | undefined;
/** What a recognizer read off an envelope's `period`. */
export interface PeriodReading {
    /** The record's (camelCase) form — present when the envelope declared a well-formed one. */
    readonly period?: DeclaredPeriod;
    /** Why a declared period was NOT read — present when it was malformed. */
    readonly problem?: PeriodProblem;
}
/**
 * Read a wire period off a recognized envelope — never repaired. `{}` when
 * the envelope declares none (`undefined` or `null`, a JSON producer's
 * `None`); `{ period }` in the record's camelCase form when it is well formed;
 * `{ problem }` when it is not, so the caller can drop it from the record and
 * say so — the model still reads what the tool wrote.
 */
export declare function readPeriod(wire: unknown): PeriodReading;
/** A declared period as detached plain data — the record's copy. */
export declare function copyPeriod(period: DeclaredPeriod): DeclaredPeriod;
/**
 * Say, once per tool per process and in dev mode only, that a recognized
 * envelope's `period` — or an absence's `provenance` — could not be read and
 * was left off the record. The envelope itself is still recognized and served
 * as the tool wrote it — read, never repaired (the `items.ts` ·
 * `readItemExtras` precedent).
 */
export declare function warnDroppedDeclaration(toolName: string | undefined, declaration: 'period' | 'provenance', problem: {
    readonly message: string;
}): void;
/**
 * Forget every dropped-declaration warning issued so far.
 * @internal test seam — the ledger is process-wide and warn-once.
 */
export declare function _resetPeriodWarnings(): void;
/**
 * How far a declared period's READ covered what it asked for — ONE pure rule
 * over the instants the tool declared; bounds are inclusive:
 *
 * ```text
 * held === 'unknown'                                  → 'unknown'
 * held.from ≤ queried.from and queried.to ≤ held.to   → 'covered'
 * queried.to < held.from or queried.from > held.to    → 'not-held'
 * otherwise                                           → 'partly-held'
 * ```
 *
 * No clock is read and no duration is parsed: the tool declared both spans.
 * Throws a `TypeError` naming the fault when handed a period that is not well
 * formed — a caller error; every period the library files was checked first.
 *
 * @example
 * ```ts
 * periodVerdict({
 *   queried: { from: '2026-09-26T09:00:00Z', to: '2026-09-26T10:00:00Z' },
 *   held: { from: '2026-08-27T02:00:00Z', to: '2026-09-26T02:00:00Z' },
 * }); // 'not-held' — the data ends at 02:00; the hour asked about is after it
 * ```
 */
export declare function periodVerdict(period: DeclaredPeriod): PeriodVerdict;
/**
 * The verdict a CALL gets when its result declared more than one period (a
 * `coverage()` around an `absent()`, each with its own): the LEAST held of
 * them, so a reader is never told more than the weakest declaration covers —
 * `not-held`, then `partly-held`, then `unknown`, then `covered`.
 */
export declare function leastHeld(verdicts: readonly PeriodVerdict[]): PeriodVerdict | undefined;
/**
 * The verdicts the MODEL is served — every verdict but `covered`, which is
 * served as nothing at all.
 *
 * @inline
 */
export type ServedPeriodVerdict = Exclude<PeriodVerdict, 'covered'>;
/** The key the served verdict word sits under, inside the served `period`. */
export declare const SERVED_VERDICT_KEY = "verdict";
/**
 * The ONE note clause per served verdict (honesty step 7b, bench round 1).
 * Static library text: no instant, no tool value, nothing interpolated — the
 * `ABSENCE_NOTE` law. Each states the CONSEQUENCE of its word in the terms the
 * notes already teach ("ground this result does NOT cover"), because the bench
 * showed a model repeating `period.queried` as the ground a result covered
 * without ever comparing it with `period.held`.
 */
export declare const PERIOD_VERDICT_CLAUSES: Readonly<Record<ServedPeriodVerdict, string>>;
/** A wire period as served: the tool's own keys, then the verdict word. */
export interface ServedPeriod {
    /** The wire period, copied, with {@link SERVED_VERDICT_KEY} last. */
    readonly period: Readonly<Record<string, unknown>>;
    readonly verdict: ServedPeriodVerdict;
    /** {@link PERIOD_VERDICT_CLAUSES}`[verdict]`. */
    readonly clause: string;
}
/**
 * What the model is served for one declared wire period — `undefined` when
 * there is nothing to add: no period, a period the rule set refuses (served
 * as the tool wrote it — read, never repaired), or a `covered` one.
 *
 * The verdict is {@link periodVerdict} over the instants the tool declared —
 * the one rule the record's `period` row is filed by, so the word the model
 * reads and the row the fold reads cannot disagree. Computed at the SERVE
 * door, never minted: the tool's own output keeps the bytes it declared, so a
 * helper in another language mints nothing new.
 *
 * @example
 * ```ts
 * servedPeriod({
 *   queried: { from: '2026-09-26T09:00:00Z', to: '2026-09-26T10:00:00Z' },
 *   held: { from: '2026-08-27T02:00:00Z', to: '2026-09-26T02:00:00Z' },
 * })?.period; // { queried: {…}, held: {…}, verdict: 'not-held' }
 * ```
 */
export declare function servedPeriod(wire: unknown): ServedPeriod | undefined;
/**
 * The inverse, for a reader of what the model was SERVED: a wire period with
 * its served verdict word removed — when that word is exactly the one
 * {@link servedPeriod} computes from the rest. Anything else (no word, a word
 * that disagrees with the instants, a period the rule set refuses) comes back
 * as the same reference, so the rule set still names it: a verdict is derived
 * by the library, never declared by a tool.
 */
export declare function unservedPeriod(wire: unknown): unknown;
/**
 * A served note with its period clause removed (the inverse of appending
 * {@link PERIOD_VERDICT_CLAUSES}`[verdict]`), or the note as found.
 */
export declare function noteWithoutClause(note: unknown, verdict: ServedPeriodVerdict): unknown;
/** A served note: the note as found, then the period clause. */
export declare function noteWithClause(note: unknown, clause: string): string;
/**
 * The `Period:` line the limits block prints for one declaring call — the
 * period AS THE TOOL DECLARED IT, instants verbatim (no reformatting, no zone
 * conversion, no verdict word: the answer's standing owns the verdict's
 * sentence). Static words around the tool's own values. With a
 * `presentation` (the run's clock zone, only under `.time()`), the instants
 * are rendered in that zone instead — see {@link periodLineInZone}.
 *
 * @example
 * ```ts
 * periodLine('backup_runs', {
 *   queried: { from: '2026-09-26T09:00:00Z', to: '2026-09-26T10:00:00Z' },
 *   held: { from: '2026-08-27T02:00:00Z', to: '2026-09-26T02:00:00Z' },
 * });
 * // 'backup_runs queried 2026-09-26T09:00:00Z to 2026-09-26T10:00:00Z; the store holds
 * //  2026-08-27T02:00:00Z to 2026-09-26T02:00:00Z'
 * ```
 */
export declare function periodLine(toolName: string, period: DeclaredPeriod, presentation?: BoundPresentation): string;
/**
 * The results layer's verdict on ONE call's period — a row on the one honesty
 * ledger (`AgentState.findingsLedger`, `kind: 'period'`), filed by the results
 * subflow at the loop head (`../../core/agent/results/subflow.ts`), never by the model.
 *
 * - `verdict` — {@link periodVerdict} over the period the call's result
 *   declared (the least held, when it declared more than one), or
 *   `'undeclared'`: the tool declares a `ToolPeriod` and this result said
 *   nothing about what its read covered — declared silence, recorded as
 *   silence.
 * - `argument` — the argument the tool's `ToolPeriod` names: the join key to
 *   the inputs layer's `argument` row for the same call (`period: true`), which
 *   says WHO chose the period, while this row says WHAT the read covered.
 *
 * The row references the call's coverage row by `toolCallId` and never copies
 * the instants: the declaration stays in its own key (`coverageDeclared`).
 * Readers that switch over every row kind must skip one they do not know.
 */
export interface PeriodRow {
    readonly kind: 'period';
    /** `AgentState.turnNumber` when the row was filed — the conversation turn. */
    readonly turn: number;
    readonly toolCallId: string;
    readonly toolName: string;
    /** The iteration of the batch the call ran in. */
    readonly iteration: number;
    readonly verdict: PeriodVerdict | 'undeclared';
    /** The argument the tool's `ToolPeriod` names — present only when it declares one. */
    readonly argument?: string;
    /** `period-differs-from-asked { missing, extra }` — the read differs from the asked range (or, for a window the model chose, from the person's). */
    readonly differs?: PeriodDiffers;
    /** `period-shifted` — the call's look-back ran as sent, `byMs` after the turn's `now`. */
    readonly shifted?: {
        readonly byMs: number;
    };
    /** `period-beyond-retention` — refused as, or read as, wholly older than the tool's source keeps. */
    readonly beyondRetention?: true;
    /** `partly-beyond-retention` — the read crosses the edge of what the source keeps; `verdict` decides. */
    readonly partlyBeyondRetention?: true;
    /**
     * The time the source holds, when it holds none or only part of what the
     * call asked about (`verdict` `not-held` / `partly-held`) — the `queried` and
     * `held` spans of the declared period that verdict came from, as the tool
     * declared them. Filed only under `.time()`, where the served time line
     * hands the model this conclusion in the person's zone (`timeLimits.ts` ·
     * `heldLine`) and the evidence gate spells it (`time/forms.ts` ·
     * `timeFormsOf`, its `held` source): the model never converts a source's
     * UTC instants itself.
     */
    readonly held?: {
        readonly queried: {
            readonly from: string;
            readonly to: string;
        };
        readonly held: {
            readonly from: string;
            readonly to: string;
        };
    };
}
/** A source's held span beside what the call asked about — {@link PeriodRow}'s `held`. */
export type HeldSpan = NonNullable<PeriodRow['held']>;
/** Every verdict a period row may carry, in the order the fold reports them. */
export declare const PERIOD_ROW_VERDICTS: readonly PeriodRow['verdict'][];
/**
 * The checkpoint door's test for a `period` row (`core/runCheckpoint.ts` ·
 * `ledgerRowIsWellFormed`) — the one owner of the row's shape, so the door
 * refuses exactly what this module never files.
 */
export declare function periodRowIsWellFormed(row: Readonly<Record<string, unknown>>): boolean;
/**
 * The one limits line for a call whose `period` row carries a time check
 * (time design § 10.2, step T8) — `undefined` when it carries none. Static
 * words around the two ranges, rendered in the presentation zone by the time
 * layer's one renderer, HANDED in bound (`time/present.ts` ·
 * `bindPresentation` → `range`, to the second, the zone named — coverage never
 * imports the renderer); the raw instants stay on the row.
 *
 * @example
 * ```ts
 * periodCheckLine(row, bindPresentation({ zone: 'America/Los_Angeles' })); // time/present.ts
 * // 'search_logs read more than was asked — asked: 2026-10-08 00:00:00–23:59:59 America/Los_Angeles
 * //  (UTC-07:00); read: 2026-10-08 00:00:00–2026-10-09 08:40:00 America/Los_Angeles (UTC-07:00)'
 * ```
 *
 * `audience` names who reads the line: the PERSON (the limits block, the
 * default — their window is "your window") or the MODEL (the served time line,
 * `agent/arguments/serve.ts` · `timeLimitsSentence` — the same window is "the
 * person's window"). That reference differs, and a SHIFTED read: the model is
 * handed the library's conclusion ({@link shiftedConclusion}) — which part of
 * the window the result does not cover, in the person's zone, and that the
 * answer says so — not the two ranges to compare (T8 bench: after a pause the
 * two-range line did not stop "1 error in the last 30 minutes", 11/20). The
 * person's line keeps its bytes.
 */
export declare function periodCheckLine(row: PeriodRow, presentation: BoundPresentation, audience?: 'person' | 'model'): string | undefined;
/**
 * The `Clocks` lines (time design § 9.6, § 10.2, step T8): one per wall-clock
 * source — a dataset whose declared axis names a zone — and, when two sources
 * declare different zones, the label that they differ. Every comparison is
 * made on instants; the lines only name the clocks.
 */
export declare function clockLines(sources: readonly SourceClock[], differ: {
    readonly zones: readonly string[];
} | undefined): string[];
//# sourceMappingURL=period.d.ts.map