/**
 * MachinePoolRegistry — the live machine-pool view (Multi-Machine Session Pool
 * §L2). Assembles a `MachineCapacity` per machine from the machine registry
 * (nickname + hardware), MachineHeartbeat (liveness), `os` (load), and
 * SessionManager diagnostics (sessions/memory), and runs the clock-skew
 * quarantine FSM. It is the input to placement (§L4) and the data behind
 * `GET /pool` + the Machines dashboard tab.
 *
 * Correctness rules from §L2 (do not weaken):
 *  - Liveness + placement freshness key on `routerReceivedAt` (the ROUTER's own
 *    clock at heartbeat arrival), NEVER the machine's self-reported timestamp —
 *    a fast-clocked machine must not appear fresher than it is.
 *  - A machine whose self-reported vs router-observed timestamps diverge beyond
 *    tolerance is quarantined via an explicit FSM (2-divergent-beats-out,
 *    2-clean-beats-in), not silently degraded.
 *
 * The pure pieces (`captureHardware`, `clockSkewTransition`) are exported so they
 * are unit-testable without I/O.
 */
import type { ClockSkewStatus, MachineCapacity, MachineHardware } from './types.js';
/** Capture this machine's static hardware properties (§L2). */
export declare function captureHardware(instarVersion?: string): MachineHardware;
export interface ClockSkewFsmState {
    status: ClockSkewStatus;
    /** Consecutive in-tolerance beats since entering suspect-clock-removed (re-admit at 2). */
    removedCleanCount: number;
}
export type ClockSkewSideEffect = 'none' | 'logged' | 'removed' | 'reset' | 're-admitted';
export declare const INITIAL_CLOCK_SKEW_STATE: ClockSkewFsmState;
/**
 * Pure transition of the clock-skew FSM (§L2 transition table). `divergent` =
 * `|selfReportedLastSeen − routerReceivedAt| > clockSkewToleranceMs` for this beat.
 * Returns the next state + the side-effect the caller must enact (removal +
 * Attention happen on 'removed'; re-admission on 're-admitted').
 */
export declare function clockSkewTransition(current: ClockSkewFsmState, divergent: boolean): {
    next: ClockSkewFsmState;
    sideEffect: ClockSkewSideEffect;
};
/** Whether a machine in this clock-skew state may receive placement. */
export declare function isPlacementEligibleByClock(status: ClockSkewStatus): boolean;
/** A heartbeat observation handed to the registry (router-side). */
export interface HeartbeatObservation {
    machineId: string;
    /** The machine's own timestamp from its heartbeat (ISO) — advisory. */
    selfReportedLastSeen?: string;
    loadAvg?: number;
    memPressure?: MachineCapacity['memPressure'];
    activeSessionCount?: number;
    maxSessions?: number;
    /** The machine's self-reported LLM-account quota state (quota-aware placement,
     *  2026-06-05). Absent = unknown (older heartbeats) = treated as not blocked. */
    quotaState?: MachineCapacity['quotaState'];
    /** Platform/workspace reachability (placement-platform-workspace-aware) — which
     *  channels this machine's adapters are connected to; consumed by placement so a
     *  channel is never owned by a machine that can't reach it. Absent = older heartbeat. */
    servesChannels?: MachineCapacity['servesChannels'];
    /** WS1.1 (MULTI-MACHINE-SEAMLESSNESS-SPEC invariant 5): the machine's
     *  self-advertised seamlessness capabilities. Absent = pre-spec peer or
     *  feature dark = non-participant (the conservative side). */
    seamlessnessFlags?: MachineCapacity['seamlessnessFlags'];
    /** Compact guard-posture summary (GUARD-POSTURE-ENDPOINT-SPEC §2.3). The
     *  caller keys the observation on the REGISTRY's machine identity — this
     *  field is the peer's self-reported DATA, never its identity. Absent =
     *  older peer / no posture (renders "unknown"). */
    guardPosture?: MachineCapacity['guardPosture'];
    /** Durable Inbound Message Queue heartbeat fields (spec §5.1). Absent =
     *  older peer / queue dark — depth honestly unknown. */
    inboundQueue?: MachineCapacity['inboundQueue'];
}
export interface MachinePoolRegistryDeps {
    /** Returns {machineId, nickname, hardware?, capabilities?} for every known machine. */
    listMachines: () => Array<{
        machineId: string;
        nickname?: string;
        hardware?: MachineHardware;
        capabilities?: string[];
        modelsAvailable?: string[];
        agentsResident?: string[];
    }>;
    /** Clock-skew divergence tolerance (ms). */
    clockSkewToleranceMs: number;
    /** A machine is offline if (now − routerReceivedAt) ≥ this (ms). */
    failoverThresholdMs: number;
    /** Wall clock (injectable for tests). */
    now?: () => number;
    /** Fired when a machine is removed from placement for clock skew (Attention item). */
    onClockQuarantine?: (machineId: string, reason: string) => void;
    logger?: (msg: string) => void;
    /** Durable last-known guard posture (GUARD-POSTURE-ENDPOINT-SPEC §2.3(c)).
     *  When wired, every posture-carrying heartbeat persists, and `assemble`
     *  falls back to the stored copy (with its REAL receipt age) for a machine
     *  with no live observation — dark-peer honesty across local restarts. */
    postureStore?: {
        record: (machineId: string, posture: NonNullable<MachineCapacity['guardPosture']>, receivedAtMs: number) => void;
        get: (machineId: string) => {
            posture: NonNullable<MachineCapacity['guardPosture']>;
            receivedAtMs: number;
        } | null;
    } | null;
}
/**
 * Tracks live per-machine state (router-observed timestamp + clock-skew FSM) and
 * assembles the MachineCapacity list. In-memory; rebuilt from heartbeats — the
 * durable machine identity/registry is the source of nickname/hardware.
 */
export declare class MachinePoolRegistry {
    private readonly d;
    private readonly observed;
    constructor(deps: MachinePoolRegistryDeps);
    private now;
    /** Record a heartbeat arrival: stamp router-clock receipt + run the clock-skew FSM. */
    recordHeartbeat(obs: HeartbeatObservation): ClockSkewSideEffect;
    /** Current clock-skew status for a machine (defaults to ok if unseen). */
    clockSkewStatus(machineId: string): ClockSkewStatus;
    /** Whether a machine is eligible for placement (online + clock ok). */
    isPlacementEligible(machineId: string): boolean;
    /** Assemble the MachineCapacity for one machine (null if unknown to the registry). */
    getCapacity(machineId: string): MachineCapacity | null;
    /** Assemble the full pool view (§L2) — the data behind GET /pool. */
    getCapacities(): MachineCapacity[];
    private assemble;
}
//# sourceMappingURL=MachinePoolRegistry.d.ts.map