/**
 * time/bind — which of the person's windows a tool call carries (time
 * design § 5.6, § 7.3): fill from one mention, bind by quote, and record a
 * differing model window and run it.
 *
 * Pattern: Walker over recorded rows. The turn's WINDOWS are read from what
 *          the record already holds — this turn's `time-answer` rows (a
 *          mention the person settled in the time ask), a `model` reader's
 *          `time-reading` rows (a reading, never the person's) and the
 *          `clock` row's `control` window — never from words. A `rule`
 *          reading settles nothing: it is a proposal the person confirms
 *          (the owner's decision "Always confirm", time design TQ29). One call's decision
 *          ({@link callWindowOf}) is a pure function of its arguments, the
 *          tool's forms and those windows.
 * Role:    L0 leaf (the time layer). Imports `convert.ts`, `range.ts`,
 *          `rows.ts`, `resolve.ts`' types and `zone.ts` only. Asked by the
 *          inputs layer (`arguments/resolve.ts`), which files the argument
 *          rows and the `call-window` row the decision implies.
 * Emits:   N/A.
 *
 * ## The laws
 *
 * - **Fill only when the turn has exactly one window.** A message holding two
 *   mentions ("this morning vs yesterday morning") fills nothing: which one a
 *   call means is the model's to say, through the quote. A mention whose
 *   reading is still open (the person has not chosen) is counted and fills
 *   nothing; a refused mention (its quote was not in the message) is not the
 *   person's words and is not counted. A `control` window (`time.window`, set
 *   in a UI) counts as one more mention with no quote.
 * - **Fill only what the model left out — exactly, else wider, never
 *   narrower.** Every argument of every form must be missing; the window goes
 *   into the first form that holds it exactly (`convert.ts` · `convertExact`),
 *   else the first that holds MORE (`convertWidened`: a whole day, the
 *   covering look-back — recorded with what it adds). No such form → the call
 *   is REFUSED, `no-form-holds` (`convert.ts` · `convertForTool`, the one
 *   answer): the tool's own rule never stands in for the person's window, so
 *   an assumed `1h` never silently reads a time the person did not ask about.
 * - **Refuse before dispatch what the tool cannot honestly read (step
 *   T5b).** A window — the person's to fill, or the model's sent — outside
 *   the tool's declared `direction`, wholly beyond its `retention` or wider
 *   than its `maxRange`; a range across days for a tool whose every form is a
 *   `day`; a window of the person's no form can read (`no-form-holds`); a
 *   sent wall time the zone skips. A window only partly beyond `retention`
 *   runs, marked. An open reading the tool can read in NO reading is refused
 *   too, and never asked.
 * - **A present window is never written over.** Bound by quote (the model's
 *   declared `user` quote names a recorded mention) or by value (the sent
 *   value, read back, IS a window of this turn); otherwise it runs as sent and
 *   is recorded `model-chosen` beside the person's window — a drill-down, a
 *   comparison and a baseline call are normal work.
 */
import { type Conversion, type PeriodFacts, type PeriodForm, type TimeRefusal, type WidenedConversion } from './convert.js';
import type { InstantText } from './instant.js';
import type { TimeRange } from './range.js';
import type { ZoneName } from './zone.js';
export { isOpenForPerson, offeredLookback, pendingQuotesOf, readerWindowsOf, turnWindowsOf, windowToConvert, type ReaderWindows, type RefusedWindow, type TurnWindow, type TurnWindows, type WindowSource, } from './windows.js';
import { type TurnWindow, type TurnWindows } from './windows.js';
/** What the inputs layer knows about one call to a tool that declares period forms. */
export interface CallToBind {
    readonly args: Readonly<Record<string, unknown>>;
    readonly forms: readonly PeriodForm[];
    /** The argument is missing from the call (`tools/declare.ts` · `isMissing`). */
    readonly isMissing: (argument: string) => boolean;
    /**
     * Under declared sources: the quotes the model declared (`source: 'user'`)
     * for this call's period arguments. Absent when the arm is off.
     */
    readonly quotes?: readonly string[];
    /**
     * The tool's declared facts (`direction`, `retention`, `maxRange`,
     * `filtersToAsked`) — a call whose window breaks one is refused before
     * dispatch (step T5b). Absent: nothing is checked.
     */
    readonly facts?: PeriodFacts;
}
/** The clock and zones a decision reads. */
export interface BindContext {
    readonly now: InstantText;
    readonly zone: ZoneName;
    readonly appZone?: ZoneName;
    readonly granularityMs: number;
}
/** The decision for one call — see {@link callWindowOf}. */
export type CallWindow = 
/** The model left every period argument out and the turn's one window went into `form` exactly. */
{
    readonly how: 'filled';
    readonly window: TurnWindow;
    /** Exact, or — when no form holds the window exactly — WIDENED (it carries `sent` and `extra`). */
    readonly conversion: Conversion | WidenedConversion;
    /** Widened, and the tool declares `filtersToAsked`: it trims its rows to the asked window. */
    readonly trimmedByTool?: true;
    readonly partlyBeyondRetention?: true;
}
/** The sent window IS one of the turn's windows — named by the model's quote (`quote`) or equal in value (`value`). */
 | {
    readonly how: 'bound';
    readonly form: number;
    readonly asked: TimeRange;
    readonly window: TurnWindow;
    readonly by: 'quote' | 'value';
    readonly partlyBeyondRetention?: true;
}
/** The sent window differs from the person's: it runs as sent (§ 7.3, the v1 law). `person` when one window is the person's. */
 | {
    readonly how: 'model-chosen';
    readonly form: number;
    readonly asked: TimeRange;
    readonly person?: TurnWindow;
    readonly partlyBeyondRetention?: true;
}
/** The sent window, and no window of the person's to compare it with. */
 | {
    readonly how: 'model';
    readonly form: number;
    readonly asked: TimeRange;
    readonly partlyBeyondRetention?: true;
}
/**
 * Refused before dispatch (step T5b): the window breaks one of the tool's
 * facts, spans days for a tool that reads one, or a sent wall time is one
 * the zone skips (`argument` names it). `asked` and `person` when known.
 */
 | {
    readonly how: 'refused';
    readonly refused: TimeRefusal;
    readonly form?: number;
    readonly asked?: TimeRange;
    readonly person?: TurnWindow;
    readonly argument?: string;
}
/** A period argument was sent, and no form reads the call's arguments back as a range. */
 | {
    readonly how: 'unread';
}
/** The model left the period out and nothing was filled — why. */
 | {
    readonly how: 'not-filled';
    readonly why: 'no-window' | 'several-mentions' | 'open-reading';
};
/**
 * Which window one call carries (the module laws). Pure: the same call, forms
 * and windows always give the same decision.
 */
export declare function callWindowOf(call: CallToBind, turn: TurnWindows, ctx: BindContext): CallWindow;
/** The range a decision says the call asks for — the person's on a fill, the sent one otherwise. */
export declare function askedRangeOf(decision: CallWindow): TimeRange | undefined;
