/**
 * RebalancePlanner — the pure Stage-3 load-rebalance decision (Multi-Machine Session
 * Pool §L4 "Load-rebalance trigger conditions"). Given the machine capacities + the
 * current session→machine assignments, it proposes a BOUNDED set of transfers off
 * over-saturated machines. It is evaluated ONLY on the heartbeat interval by the
 * caller (never per message), and is deliberately conservative to avoid a cascade:
 *
 *  - A machine is a rebalance SOURCE only if its session ratio exceeds
 *    `rebalanceThresholdPercent` (default 0.85 of maxSessions).
 *  - Only NON-pinned, low-priority sessions that are off cool-down
 *    (`now - lastTransferredAt > placementCooldownMs`) are movable; a hard pin or a
 *    critical session is NEVER proactively rebalanced.
 *  - At most ONE move per source per cycle (capped overall by `maxMovesPerCycle`), and
 *    a working copy of capacities is updated as moves are proposed so the planner never
 *    piles every session onto one target.
 *  - The TARGET is chosen by the same `PlacementExecutor.decide(reason:'rebalance')`
 *    the router uses — a move is proposed only if it lands on a DIFFERENT, eligible
 *    machine. No move ⇒ empty result (rebalance never forces a churn).
 *
 * Pure over its inputs; the caller performs the actual transfers (TransferOrchestrator).
 */
import type { PlacementExecutor, TopicPlacement } from './PlacementExecutor.js';
import type { MachineCapacity } from './types.js';
export interface RebalanceSession {
    sessionKey: string;
    ownerMachineId: string;
    pinned?: boolean;
    lowPriority?: boolean;
    lastTransferredAt?: number;
    topicMetadata?: TopicPlacement;
}
export interface RebalanceInput {
    machines: MachineCapacity[];
    sessions: RebalanceSession[];
    rebalanceThresholdPercent: number;
    placementCooldownMs: number;
    now: number;
    /** Hard cap on moves proposed per cycle (default = number of saturated sources). */
    maxMovesPerCycle?: number;
}
export interface RebalanceMove {
    sessionKey: string;
    fromMachine: string;
    toMachine: string;
    reason: string;
}
export declare function planRebalance(input: RebalanceInput, placement: PlacementExecutor): RebalanceMove[];
//# sourceMappingURL=RebalancePlanner.d.ts.map