/** * ResourceGovernor — Never-OOM class-based admission (T11999, Epic T11992). * * Admits resource-intensive work through priority classes whose slot budgets * are computed at acquire time from host memory + memory-pressure (PSI). A * denial returns a structured, retryable {@link ResourceDeferral} — never a * silent drop, never a crash. Existing grants are NEVER revoked. * * Three modes (verbatim writer-lease shape, `writer-lease.ts` `resolveLeaseMode`): * - `supervisor` — defer to the Rust `cleo-supervisor` `resource_admit` verb. * Demotes to `local` (log-once) until the IPC client is wired — a * dead/absent arbiter must never deadlock work. * - `local` — DEFAULT, daemon-off. Per-class slot directories under * `getCleoHome()/locks/resource-/` arbitrated by `proper-lockfile` * (crash-stale auto-release ⇒ genuinely cross-process without a daemon), * plus a point-sample of the {@link ResourceMonitor} taken INSIDE acquire. * Generalizes the tool-semaphore engine (`tool-semaphore.ts`). * - `off` — pure pass-through. * * `interactive-cli` is NEVER gated; `full-build` is pinned to one machine-wide * slot regardless of pressure. * * @task T11999 * @epic T11992 * @adr resource-governor-never-oom-architecture §3.4 */ import { type AdmissionResult, type GovernorMode, type ResourceClass } from '@cleocode/contracts'; import type { ResourceSample } from './backend.js'; import { ResourceMonitor } from './monitor.js'; /** * Resolve the governor mode from `CLEO_RESOURCES_MODE`, once per process. * Unknown / unset values resolve to `'local'` — the production-safe default * while the supervisor daemon is disabled. * * @task T11999 */ export declare function resolveGovernorMode(): GovernorMode; /** * Reset cached process-global state (mode + degrade flag). Tests only. * @internal */ export declare function _resetGovernorStateForTest(): void; /** Tunables for budget computation. All optional; sane defaults applied. */ export interface BudgetOptions { /** RAM reserved for the OS + interactive use, in MiB. Default 2048. */ readonly headroomMb?: number; /** Estimated RAM per agent session (incl. ~300 MB MCP suite), MiB. Default 4096. */ readonly agentEstRamMb?: number; /** `some avg10` (pp) at/above which test/build budgets halve. Default 10. */ readonly holdSomeAvg10?: number; /** `some avg10` (pp) at/above which test/build budgets floor to 1. Default 25. */ readonly floorSomeAvg10?: number; /** Override CPU count (tests). Default {@link availableParallelism}. */ readonly cpuCount?: number; /** Override total RAM bytes (tests). Default {@link totalmem}. */ readonly totalMemBytes?: number; } /** * Compute the slot budget for a class given a point-sample. * * - `interactive-cli` → `Infinity` (never gated). * - `full-build` → `1` machine-wide, pressure-independent. * - `agent-session` → `clamp(1, ⌊(MemAvailable − headroom)/estRamMb⌋, cpus−2)`. * - `test-run` / `scoped-build` → `max(1, ⌊cpus/4⌋)`, ×0.5 when `some>hold`, * floored to 1 when `some>floor`. * - `llm-call` → `max(1, cpus−2)` (primarily gated by the llm-queue elsewhere). * - `db-heavy` → `1`, deferred (→0) under `backoff`-level pressure. * - `background-autonomous` → `1` only when pressure is `ok`, else `0`. * * @adr resource-governor-never-oom-architecture §3.4 (budgets) */ export declare function computeClassBudget(cls: ResourceClass, sample: ResourceSample, opts?: BudgetOptions): number; /** * Machine-wide slot directory for a class, under * `getCleoHome()/locks/resource-/`. Shared across projects, worktrees, * and PIDs — exactly like the tool semaphore. */ export declare function governorSlotDir(cls: ResourceClass): string; /** Options for {@link ResourceGovernor.acquire}. */ export interface AcquireOptions extends BudgetOptions { /** * When `false`, a single non-blocking pass — returns a {@link ResourceDeferral} * immediately if no slot is free (admission semantics; spawn/wave clamp). * When `true` (default), polls until a slot frees or `timeoutMs` elapses * (queue semantics; heavy ops). On timeout, returns a deferral. */ readonly blocking?: boolean; /** Max wall-clock to wait in blocking mode (ms). Default 3_600_000. */ readonly timeoutMs?: number; /** Poll interval in blocking mode (ms). Default 200. */ readonly pollMs?: number; /** * Inject a pre-taken sample (tests, or to avoid re-sampling). When omitted, * a fresh point-sample is taken inside acquire. */ readonly sample?: ResourceSample; /** Inject a monitor (tests). Default a fresh {@link ResourceMonitor}. */ readonly monitor?: ResourceMonitor; } /** * The Never-OOM admission gate. Stateless wrapper over the mode-resolved * backend (local slot dirs today; supervisor IPC when wired). Construct once * and share, or use the module-level {@link governor} singleton. */ export declare class ResourceGovernor { /** * Acquire one slot of `cls`. Returns a {@link ResourceGrant} on success or a * {@link ResourceDeferral} on denial. Never throws for admission control; * only genuinely unexpected I/O errors propagate. */ acquire(cls: ResourceClass, opts?: AcquireOptions): Promise; /** * Route an admission through the supervisor's central `resource_admit` verb. * Returns a grant (whose `release` calls `resource_release`) or a deferral, or * `null` when the supervisor is unreachable so the caller degrades to the * local slot engine. Never throws — a dead arbiter never deadlocks work. * * @task T12001 */ private acquireViaSupervisor; /** Non-blocking single-pass acquire (admission semantics). */ tryAcquire(cls: ResourceClass, opts?: AcquireOptions): Promise; /** * Currently-grantable slot count for `cls` = budget − held. Held is the count * of slot files currently locked. `Infinity` for ungated classes. */ available(cls: ResourceClass, opts?: AcquireOptions): Promise; } /** Count of slot files for a class (debug/introspection). */ export declare function slotFileCount(cls: ResourceClass): number; /** Process-wide governor singleton. */ export declare const governor: ResourceGovernor; //# sourceMappingURL=governor.d.ts.map