import type { BlackboardEngine } from "./blackboard.js"; import type { BlackboardEntry } from "../utils/types.js"; import type { IBlackboardStore, IIndexManager } from "../storage/interfaces.js"; /** * Sentinel cutoff meaning "no age filter". The auto-archive trigger and the * sweep it fires MUST both use it: if the trigger counts future-stamped * entries (clock rolled back, git-synced store authored on a faster clock) * but the sweep's cutoff=now excludes them, the trigger re-fires on every * post while archiving nothing — the #35 counted-but-never-archived loop * through the clock-skew door. */ export declare const NO_AGE_CUTOFF = "9999-12-31T23:59:59.999Z"; export interface ArchivePartitionOptions { before?: string; keep_decisions?: boolean; /** Exempts unresolved needs, warnings, AND open questions (D4 widened * the set to match triage's open-obligation concept). */ keep_open_needs_warnings?: boolean; /** * Count-based retention (D4): keep the newest `retain` non-exempt entries * on the board regardless of age. Count-based, not age-based, because the * #35 field outage proved an age cutoff cannot bound a same-hour burst. * Undefined/0 = no retention (legacy explicit-call semantics). */ retain?: number; } export interface ArchivePartition { to_archive: BlackboardEntry[]; kept_open_count: number; retained_count: number; cutoff: string; } /** * THE archive partition — the single source of truth for "what would a sweep * archive". Used by Archiver.plan()/archive() AND by the blackboard * auto-archive trigger count: the two MUST stay the same function, because * any entry class that is counted by the trigger but never archived by the * sweep re-arms the trigger permanently (the #35 auto-archive feedback * loop). Sharing the partition makes that drift impossible by construction. */ export declare function partitionArchivable(allEntries: BlackboardEntry[], resolvedIds: Set, options?: ArchivePartitionOptions): ArchivePartition; export declare class Archiver { private readonly twiningDir; private readonly blackboardStore; private readonly blackboardEngine; private readonly indexManager; constructor(twiningDir: string, blackboardStore: IBlackboardStore, blackboardEngine: BlackboardEngine, indexManager: IIndexManager | null); /** * Compute the archive partition without touching the store (#39). * Entries before the cutoff are archivable UNLESS they are decisions * (LIFE-03) or unresolved need/warning/question entries (#40, widened to * questions by D4). An item counts as resolved when explicitly resolved * (status "resolved", D2) or when any other entry back-references it via * relates_to — age is the wrong archival signal for open obligations, * which matter MORE as they age, not less. `retain` keeps the newest K * archivable entries on the board (D4 count-based retention). */ plan(options?: ArchivePartitionOptions): Promise; /** * Archive old blackboard entries. * Decision entries are never archived (LIFE-03); unresolved need/warning * entries are exempt unless keep_open_needs_warnings is false (#40). * Archived entries are moved to archive/{YYYY-MM-DD}-blackboard.jsonl. * Optionally posts a summary finding (LIFE-02). */ archive(options?: ArchivePartitionOptions & { summarize?: boolean; }): Promise<{ archived_count: number; archive_file: string; kept_open_count: number; retained_count: number; summary?: string; }>; /** Build a human-readable summary of archived entries. */ private buildSummary; } //# sourceMappingURL=archiver.d.ts.map