/** * CalendarSlotter — deterministic LLM-free slot-fill (spec-20260628-calendar-planner Sprint 1). * * PURITY CONTRACT: pure synchronous only — no fs, no network, no LLM import, no subprocess, no dynamic eval. * Identical input => identical output. * * Algorithm: * 1. Derive free intervals from (window minus busy intervals), clamped to workingHours if set. * 2. Iterate findings in INPUT ORDER (pre-ranked by the hub — the LLM NEVER packs slots). * 3. Place each finding into the earliest free interval that fits estDurationMin before dueBy. * 4. On placement, split the consumed free interval in-place. * 5. If no interval fits, push to unscheduled with an exhaustive-switch reason. * * Time math uses Date.parse(iso) → epoch-ms arithmetic (pure — same ISO always yields same ms). * new Date(ms).toISOString() converts back to ISO-8601 (also pure — deterministic). */ import type { Finding, BusyInterval, SlotConstraints, ProposedPlan } from "./types.js"; /** * Place ranked findings into free calendar slots deterministically. * * - findings are processed in INPUT ORDER (= priority order from the hub). * - Each finding is placed into the earliest free interval that can accommodate * its estDurationMin (default: 30 min) entirely before its dueBy. * - On placement the consumed portion is removed from the free-interval list. * - Findings that cannot be placed are returned in unscheduled[] with a reason. * - No LLM, no network, no fs, no clock — deterministic across identical inputs. * * @param findings - Pre-ranked Finding array (index 0 = highest priority). * @param busy - Known busy intervals for the planning window. * @param constraints - Window bounds (and optional working-hours clamp). * @returns ProposedPlan with scheduled PlanItems and unscheduled entries. */ export declare function planSlots(findings: Finding[], busy: BusyInterval[], constraints: SlotConstraints): ProposedPlan; //# sourceMappingURL=slotter.d.ts.map