import type { LinkRecord, MemoryRecord } from "./types.js"; /** * READ-ONLY preview of sleep consolidation (SPEC/sleep-consolidation-work-to-spec-arch): * cluster settled WORK memories so a human can eyeball what a future `sleep` * pass WOULD fold together. This module mutates nothing and must stay that way * until the Phase-2 go/no-go — the write-back (`sleep_apply`) is a separate, * gated feature with its own invariant harness. * * Edges: an existing link of any type, or raw cosine >= minCosine. The * threshold is raw cosine, NOT the blended recall score — council 2026-06-30: * clustering must use a semantic-only floor above the band where unrelated * same-domain memories land (~0.485 raw on bge-small; paraphrase ~0.882). * Clusters never span projects: cross-project cosine is indistinguishable from * same-project noise and provenance collapses under synthesis. */ export interface SleepClusterMember { id: number; /** The durable identity — ids churn on index rebuilds, paths do not. */ relative_path: string; name: string; updated_at: string; size: number; } export interface SleepCluster { project_name: string; /** Ordered oldest-first by updated_at. */ members: SleepClusterMember[]; /** Mean pairwise raw cosine over member pairs that both have embeddings. */ mean_cosine: number; link_edges: number; cosine_edges: number; oldest: string; newest: string; } export interface ClusterInput { /** Eligible memories (already filtered to kind WORK and settled age). */ memories: MemoryRecord[]; embeddings: Map; links: LinkRecord[]; minCosine: number; } export declare function clusterSleepCandidates(input: ClusterInput): SleepCluster[]; export declare function renderSleepCandidatesText(clusters: SleepCluster[], eligible: number, minCosine: number, minAgeDays: number): string;