/** * B7 S5 — Archivist reasoning budget. * * Adds a deterministic "reasoning pass" over a snapshot of knowledge entries * that emits PROPOSALS (compress, demote, flag_drift) for the Resolutionist * to consider. Never mutates knowledge directly. Never calls an LLM. Pure * function over a snapshot — safe to run in the Archivist scan loop and * fully testable without a database. * * Proposals are inert until a Resolutionist acts on them. They land on the * staff event bus as `actionType: 'reasoning_proposal_emitted'` and are * included in the ArchivistReport so the caller can ship them as-is. * * Shape: * planArchivistReasoningPass({ candidates, now, reasoningBudget }) * → { proposals, budgetUsed, note } */ /** * Minimal snapshot of a knowledge entry required for reasoning. The Archivist * runtime maps its Prisma rows to this shape before calling the helper so the * helper itself is database-free and fully unit-testable. */ export interface ArchivistReasoningCandidate { id: string | number; entityType: string; entityId: string; key: string; confidence: number; source: string; lastAccessedAt: Date | string | null; updatedAt: Date | string | null; createdAt: Date | string | null; summary?: string | null; valueSummary?: string | null; stability?: number | null; } export type ArchivistReasoningAction = 'compress' | 'demote' | 'flag_drift' | 'review_stale'; export interface ArchivistReasoningProposal { action: ArchivistReasoningAction; /** One or more candidate ids this proposal targets. */ targetIds: (string | number)[]; /** Human-readable entityKey fingerprint for the first target. */ primaryEntityKey: string; reason: string; /** 0-100 — the helper's confidence in the proposal. */ confidence: number; /** * Snapshot metadata that downstream consumers (Resolutionist, observability) * can use to inspect the cluster without re-querying the database. */ snapshot: { targetCount: number; minConfidence: number; maxConfidence: number; oldestLastAccessedAt: string | null; newestLastAccessedAt: string | null; }; } export interface ArchivistReasoningPassOutput { proposals: ArchivistReasoningProposal[]; budgetUsed: number; budgetMax: number; note: string; /** Reason the pass either ran, was skipped, or was capped. */ outcome: 'no_candidates' | 'no_proposals' | 'proposals_emitted' | 'budget_capped' | 'budget_zero'; } export interface PlanArchivistReasoningPassInput { candidates: ArchivistReasoningCandidate[]; /** Max number of proposals the pass is allowed to emit in one cycle. */ reasoningBudget: number; /** Defaults to new Date(). Pass a fixed value in tests for determinism. */ now?: Date; /** Low-confidence review threshold (default 55). */ reviewConfidenceThreshold?: number; /** Days without access after which a fact is flagged for stale review. */ staleAccessDays?: number; /** Minimum cluster size to propose compression. */ compressMinClusterSize?: number; } export declare const ARCHIVIST_REASONING_DEFAULT_BUDGET = 5; export declare const ARCHIVIST_REVIEW_CONFIDENCE_THRESHOLD = 55; export declare const ARCHIVIST_STALE_ACCESS_DAYS = 21; export declare const ARCHIVIST_COMPRESS_MIN_CLUSTER_SIZE = 3; /** * Pure function. Examines a candidate snapshot and emits a bounded list of * reasoning PROPOSALS. Never calls an LLM. Never mutates. Deterministic for * a given input. Safe to unit-test. * * Proposal rules (in priority order): * 1. compress — ≥ compressMinClusterSize candidates share the same * entityType/entityId/key cluster (duplicates to collapse). * 2. flag_drift — a cluster has high variance (> 30) in confidence, suggesting * repeated re-writes that disagree with each other. * 3. demote — a single candidate sits below reviewConfidenceThreshold * AND has not been accessed for staleAccessDays. * 4. review_stale — a candidate has not been accessed for ≥ 2× staleAccessDays * regardless of confidence. */ export declare function planArchivistReasoningPass(input: PlanArchivistReasoningPassInput): ArchivistReasoningPassOutput; //# sourceMappingURL=archivistReasoning.d.ts.map