/** * Cooperative CPU and heap caps for a full-pass chore. * * Realtime and scoped drains never consult this module. The scheduler calls * {@link FullPassCapController.applyAtCheckpoint} only from a full-pass chore * checkpoint. Sleeps here are additional yield points: each slice re-runs the * realtime hand-off so admission stays inside the #609 deadline. */ import type { FlagSnapshot } from "@indigoai-us/hq-flags-client"; export declare const FULL_PASS_CPU_CAP_FLAG = "sync.full-pass.cpu-cap-pct"; export declare const FULL_PASS_HEAP_CAP_FLAG = "sync.full-pass.heap-cap-mb"; export declare const DEFAULT_FULL_PASS_CPU_CAP_PCT = 25; export declare const DEFAULT_FULL_PASS_HEAP_CAP_MB = 512; export declare const FULL_PASS_CPU_WINDOW_MS = 10000; export declare const FULL_PASS_CPU_SLEEP_MIN_MS = 50; export declare const FULL_PASS_CPU_SLEEP_MAX_MS = 2000; export declare const FULL_PASS_HEAP_PAUSE_MAX_MS = 5000; export declare const FULL_PASS_HEAP_PAUSE_BUDGET_MS = 60000; export declare const FULL_PASS_HEAP_PAUSE_DROP_FRACTION = 0.05; export declare const FULL_PASS_UNIT_SIZE_DEFAULT = 500; export declare const FULL_PASS_UNIT_SIZE_FLOOR = 50; export declare const FULL_PASS_DECODE_WINDOW_FLOOR = 1000; export declare const FULL_PASS_CAP_PROGRESS_MS = 60000; export declare const FULL_PASS_CAP_RESUME_FRACTION = 0.9; export declare const FULL_PASS_CAP_RESUME_DWELL_MS = 30000; export declare const FULL_PASS_CAP_RESUME_DWELL_CHECKPOINTS = 10; export type FullPassCapFlags = { cpuCapPct: number; heapCapMb: number; source?: "flag" | "platform-default"; }; export type FullPassCapFlagSource = { read(): FullPassCapFlags | Promise | null; refresh?(): Promise; }; export type CpuUsageSample = { user: number; system: number; }; export type FullPassCapLog = { event: "full-pass-cap"; kind: "cpu" | "heap"; action: "throttle" | "shrink" | "pause" | "pause-exhausted" | "resume" | "defaults" | "progress" | "complete"; platform?: string; cpuCapPct?: number; heapCapMb?: number; source?: "flag" | "platform-default"; observed: number; cap: number; extra?: Record; }; export type FullPassCapSummary = { capThrottledMs: number; peakHeapUsedMb: number; minDecodeWindow: number; minUnitSize: number; sleeps: number; }; type CapDeps = { now?: () => number; cpuUsage?: () => CpuUsageSample; memoryUsage?: () => { heapUsed: number; rss: number; }; sleep?: (ms: number) => Promise; write?: (line: string) => void; flags?: FullPassCapFlagSource; platform?: string; }; export declare function resetFullPassCapLogForTest(): void; export declare function takeLastFullPassCapSummary(): FullPassCapSummary | null; export declare function getActiveFullPassDecodeWindow(): number; export declare function getActiveFullPassUnitSize(): number; /** Must stay ref'd: this is often the only handle while a chore yields. */ export declare function fullPassCapSleep(ms: number): Promise; export declare function platformCapDefaults(platform: string): FullPassCapFlags; export declare function flagsFromSnapshot(snapshot: FlagSnapshot | null, platform: string): FullPassCapFlags; export declare function createHqFlagsCapSource(options: { endpoint?: string; getToken?: () => string | Promise; fetch?: typeof fetch; write?: (line: string) => void; platform?: string; }): FullPassCapFlagSource; export declare class FullPassCapController { private readonly deps; readonly decodeWindowDefault = 10000; decodeWindow: number; unitSize: number; private flags; private markCpu; private markWall; private samples; private throttledMs; private sleeps; private peakHeapUsed; private minDecodeWindow; private minUnitSize; private shrunkSinceOver; private cpuState; private heapState; private cpuProgressAt; private heapProgressAt; private running; private announced; private source; private heapPauseMs; private lastPauseHeapUsed; private pauseExhausted; private cpuBelowSince; private cpuBelowCount; private heapBelowSince; private heapBelowCount; constructor(deps?: CapDeps); applyFlags(flags: FullPassCapFlags): void; beginChore(): void; endChore(): FullPassCapSummary; /** Drop the active override so a realtime/scoped drain sees default batches. */ suspendForHandoff(): void; /** Call after a realtime hand-off so that work is not billed to the chore. */ resumeAfterHandoff(): void; applyAtCheckpoint(handoff: () => Promise): Promise; private adoptFlags; private noteSlice; private trimWindow; private trailingSharePct; private sleepMsForShare; private resumeThreshold; private dwellMet; private applyCpu; private applyHeap; private shrink; private yieldSleep; private maybeProgress; private emit; private write; private writer; private announceResolved; private platform; private now; private readCpu; private readMem; } export {}; //# sourceMappingURL=full-pass-caps.d.ts.map