/**
 * time/resolveRecord — what the resolver writes down: the candidate and
 * choice shapes, the app's policy (read at `.time()`), and the checks the
 * checkpoint door runs on a filed reading.
 *
 * Pattern: the record half of `resolve.ts`, split from the resolver so the
 *          SYNCHRONOUS doors — `.time({ policy })` (`clock.ts` ·
 *          `readTimeOptions`) and `validateCheckpoint` (`rows.ts` ·
 *          `timeRowIsWellFormed`) — reach the shapes and their checks without
 *          the resolver, which only an armed seed loads (`agent/stages/
 *          timeLayer.ts`, through `import()`: the optional-family law of
 *          docs-next's site budget). `resolve.ts` re-exports everything here.
 * Role:    L0 leaf (the time layer). Imports `range.ts` and `zone.ts`
 *          (the window check) only.
 * Emits:   N/A.
 *
 * @example
 * ```ts
 * readPolicy({ dateOrder: 'DMY' }); // { dateOrder: 'DMY', year: 'ask' }
 * readPolicy({ abbreviations: { PST: { zone: 'America/Los_Angeles', offset: '-08:00' } } });
 * // { dateOrder: 'ask', year: 'ask', abbreviations: { PST: { zone: 'America/Los_Angeles', offset: '-08:00' } } }
 * candidateIsWellFormed({ kind: 'range', range: { from: 'x', to: 'y' } }); // false
 * ```
 */
import type { InstantText } from './instant.js';
import type { DurationText } from './duration.js';
import { type TimeRange } from './range.js';
import { type ZoneName } from './zone.js';
import type { Grain } from './present.js';
/** A part of a time a person can say. `duration`: the length of a look-back ("last 40 minutes"). */
export type TimePart = 'year' | 'month' | 'day' | 'hour' | 'minute' | 'second' | 'meridiem' | 'zone' | 'duration';
/** What was asked, before the clock is applied. */
export type TimeWindow = {
    readonly kind: 'range';
    readonly range: TimeRange;
}
/** Always "until the clock's now". */
 | {
    readonly kind: 'lookback';
    readonly duration: DurationText;
};
/** A library-written note on how a window was read. */
export type TimeNote = 
/**
 * The window's END was widened to the end of its last said grain: "to 8:40"
 * → `08:41`, a day → the next midnight, a lone "9 AM" → `[09:00, 10:00)`.
 * Never on a range end said as an o'clock hour ("8 AM to 9 AM" ends AT
 * `09:00`, § 3.3). Ask {@link widenedGrain}, never `grain` alone.
 */
{
    readonly kind: 'end-of-grain';
}
/** A wall time the clocks go back through: which of its two instants this is (`end`: which end of a range). */
 | {
    readonly kind: 'dst-overlap';
    readonly which: 'earlier' | 'later';
    readonly end?: 'from' | 'to';
}
/** A wall time the clocks skip: which of Temporal's two readings this is. */
 | {
    readonly kind: 'dst-gap';
    readonly which: 'earlier' | 'later';
    readonly end?: 'from' | 'to';
}
/** The person said a numeric offset, not a zone: the instants carry it; `zone` is the clock's. */
 | {
    readonly kind: 'offset-said';
    readonly offset: string;
}
/** A two-digit year, read in the clock's century. */
 | {
    readonly kind: 'century-implied';
    readonly century: number;
}
/**
 * The person named the zone in words that are no zone name (`London time`,
 * `PST`): `token` as written, and how the library read it — the one IANA
 * zone the place names (`place`), the app's abbreviation map's zone
 * (`abbreviation`), or the fixed offset the abbreviation spells
 * (`abbreviation-literal`). A proposal like every reading: the person
 * confirms the zone with the window.
 */
 | {
    readonly kind: 'zone-read';
    readonly token: string;
    readonly as: 'place' | 'abbreviation' | 'abbreviation-literal';
};
/** Which reading of the PARTS produced a candidate, so a policy — or an ask — can choose among them. */
export interface ReadingTags {
    readonly dateOrder?: 'MDY' | 'DMY' | 'YMD';
    /** The meridiem this reading gave a clock time said without one (the `from` end of a range). */
    readonly meridiem?: 'am' | 'pm';
    /** The same, for the `to` end of a range. */
    readonly endMeridiem?: 'am' | 'pm';
    readonly year?: 'said' | 'current' | 'previous';
    /** An abbreviation in the app's map: read as its zone (`zone`) or as its literal offset (`literal`). */
    readonly abbreviation?: 'zone' | 'literal';
}
/** A window read from words, resolved against the clock (§ 3.2). */
export interface ResolvedWindow {
    readonly window: TimeWindow;
    /** Always present: a look-back resolved against the clock. Spelled in the offset the person meant. */
    readonly range: TimeRange;
    /** The zone the person meant, else the clock's. */
    readonly zone: ZoneName;
    /** The finest part the person said. */
    readonly grain: Grain;
    /** The parts the person said — empty for a `model` reader's reading (§ 5.5). */
    readonly said: readonly TimePart[];
    /** The parts this module filled: from the clock, the policy's candidates, the century. */
    readonly implied: readonly TimePart[];
    readonly anchor: 'message' | 'previous-window' | 'none';
    readonly reader: {
        readonly id: string;
        readonly kind: 'rule' | 'model';
    };
    readonly notes: readonly TimeNote[];
}
/** One candidate — produced here, never by a strategy. */
export interface TimeCandidate extends ResolvedWindow {
    readonly reading: ReadingTags;
    /** Which of the mention's parses it came from. */
    readonly parse: number;
}
/**
 * One zone abbreviation the app's people write, as data (§ 11): the zone it
 * stands for, and the fixed offset it literally spells. `PST` in October is
 * both `America/Los_Angeles` (−07:00, what a person on the US west coast
 * usually means) and −08:00 (what the letters say) — so a mismatch offers
 * BOTH readings, never corrects one into the other.
 */
export interface ZoneAbbreviation {
    readonly zone: ZoneName;
    /** `±HH:MM` (or `±HH`, `±HHMM`). */
    readonly offset: string;
}
/** The v1 policy (§ 11): the switches with careful answers. */
export interface TimePolicy {
    /** `'ask'`: a numeric date's readings become choices. Or the one order this app's people write. */
    readonly dateOrder: 'ask' | 'MDY' | 'DMY' | 'YMD';
    /** `'ask'`: a date said without a year is asked. `'current'`: the clock's year, recorded as assumed. */
    readonly year: 'ask' | 'current';
    /**
     * Absent (the default): no abbreviation maps to a zone — `PST` is ASKED as
     * a zone. Present: the abbreviations this app's people write, each read as
     * its zone AND as its literal offset when the two disagree at the instant
     * (both offered in the one confirmation, noted `zone-read`). An
     * abbreviation missing from the map is still asked. No map ships.
     */
    readonly abbreviations?: Readonly<Record<string, ZoneAbbreviation>>;
}
/** No silent MDY, no guessed year. */
export declare const DEFAULT_TIME_POLICY: TimePolicy;
/** What the clock gives the resolver. */
export interface ResolveClock {
    readonly now: InstantText;
    readonly zone: ZoneName;
    /**
     * The clock's `zoneSource` (`clock.ts` · `TimeClock`). `'unknown'` (G15):
     * `zone` is only the UTC spelling, so a mention that names no zone of its
     * own is not resolved — the person's zone is asked first.
     */
    readonly zoneSource?: string;
}
/** Every candidate of one mention, and what kept a parse from any. */
export interface MentionResolution {
    readonly candidates: readonly TimeCandidate[];
    /** A zone the person said that names no zone this layer can read (`PST`): the zone must be asked. */
    readonly needsZone: boolean;
    /** Parts v1 does not resolve, named. */
    readonly unsupported: readonly string[];
}
/** A question only the person can settle. `abbreviation`: the app's map's zone, or the letters' offset. */
export type OpenQuestion = 'date-order' | 'year' | 'meridiem' | 'dst' | 'zone' | 'abbreviation' | 'parse' | 'confirm';
/** How a mention's reading settled — recorded on its `time-reading` row. */
export type ReadingChoice = 
/** Every candidate left names the same window. */
{
    readonly by: 'only';
    readonly candidate: number;
}
/** The policy removed a reading and one window is left — assumed, recorded. */
 | {
    readonly by: 'policy';
    readonly candidate: number;
    readonly policy: Partial<TimePolicy>;
}
/** An ask must settle it (a later step raises it): the candidates left and the questions. */
 | {
    readonly by: 'open';
    readonly remaining: readonly number[];
    readonly open: readonly OpenQuestion[];
    readonly policy?: Partial<TimePolicy>;
} | {
    readonly by: 'none';
    readonly why: 'unreadable' | 'unsupported' | 'no-candidate' | 'excluded-by-policy';
};
/**
 * A numeric offset as written (`-07`, `-0700`, `-07:00`) → minutes east of
 * UTC and its `±HH:MM` spelling, or `undefined`. The one reader of an offset
 * token: `resolve.ts` · `zoneReadsOf` (a said offset) and {@link readPolicy} (an
 * abbreviation's literal offset) both ask it.
 */
export declare function offsetOfToken(token: string): {
    readonly minutes: number;
    readonly spelled: string;
} | undefined;
/**
 * The app's `policy`, read with the v1 defaults filled in — or a problem in
 * words (an unknown key, a value outside its switch). `abbreviations` is kept
 * only when given, so a policy without it reads byte-identical to v1's.
 */
export declare function readPolicy(value: unknown): TimePolicy | string;
/**
 * The grain a candidate's END was widened to, or `undefined` when its `to`
 * is exact — the one answer to "was the end widened?" (§ 3.3). A label
 * renders the end as said only then (`readingAsk.ts` · `timeAskOf`), and
 * the said end is `to − 1 grain` only then (`forms.ts` · `saidEndMs`).
 * `grain` alone is not the answer: "8 AM to 9 AM" is grain `hour` and ends
 * AT `09:00`; a look-back is grain `hour` and ends at the clock's now.
 *
 * @example
 * ```ts
 * widenedGrain({ grain: 'minute', notes: [{ kind: 'end-of-grain' }] }); // 'minute' — [08:00, 08:41)
 * widenedGrain({ grain: 'hour', notes: [] });                          // undefined — [08:00, 09:00)
 * ```
 */
export declare function widenedGrain(candidate: Pick<TimeCandidate, 'notes' | 'grain'>): Grain | undefined;
/**
 * The grain a candidate's LABEL shows its end at (`readingAsk.ts` ·
 * `timeAskOf`), or `undefined` to show the range as it is. A widened end is
 * shown as said ({@link widenedGrain}). A look-back is the other kept-inside
 * end: `[now − L, now + 1 ms)` holds the clock's now, so its label ends AT now,
 * at the grain the person counted in — "last 40 minutes" is `8:00 – 8:40 AM`,
 * never `8:40:00.001`. Only the label asks this: a look-back's end was not
 * widened to a grain, so the said end (`forms.ts` · `saidEndMs`) keeps asking
 * {@link widenedGrain}.
 *
 * @example
 * ```ts
 * shownGrain({ window: { kind: 'lookback', duration: '40m' }, grain: 'minute', notes: [] }); // 'minute'
 * shownGrain({ window: { kind: 'range', range }, grain: 'hour', notes: [] });               // undefined — "8 AM to 9 AM"
 * ```
 */
export declare function shownGrain(candidate: Pick<TimeCandidate, 'notes' | 'grain' | 'window'>): Grain | undefined;
/** The parts a candidate can name, in the order a record lists them. */
export declare const PART_ORDER: readonly TimePart[];
/** Whether `value` is a candidate this module would have written. */
export declare function candidateIsWellFormed(value: unknown): boolean;
/** Whether `value` is a choice this module would have written over `count` candidates. */
export declare function choiceIsWellFormed(value: unknown, count: number): boolean;
