/**
 * Bare-metal scaler backend implementation.
 *
 * Manages ephemeral agent processes using child_process.spawn.
 * Uses detached process groups for clean killing of entire process trees.
 * All agents are single-use: destroyed after job completion.
 */
import { type ToolRequirement } from '@kici-dev/shared';
import type { AgentTokenStore } from '../agent/token-store.js';
import type { ScalerBackend, ScalerEntry, ManagedAgent, LabelSetConfig, LogCapture, ResourceRequest, ScalerEventCallback, ValidationResult, EffectiveLimits } from './types.js';
export interface BareMetalScalerBackendOptions {
    /** Human-readable name for this scaler */
    name: string;
    /** Label sets this backend can provision */
    labelSets: LabelSetConfig[];
    /** Maximum concurrent agents */
    maxAgents: number;
    /** Default resource limits applied when label set has none */
    defaultResources?: ResourceRequest;
    /** Token store for creating ephemeral agent auth tokens. Optional -- when undefined, no token is injected. */
    tokenStore?: AgentTokenStore;
    /** TTL for ephemeral agent tokens in ms. Default: 1 hour. */
    tokenTtlMs?: number;
    /** Agent roles for this scaler. undefined = all, [] = execution only. */
    roles?: string[];
    /**
     * When true, wrap each spawned agent process in a transient systemd scope
     * (`systemd-run --user --scope --slice=kici-scaler`) and translate the
     * job's effective CPU / memory limits into `CPUQuota=` / `MemoryMax=`
     * properties so the kernel cgroup actually enforces the limits. When
     * false (the default), bare-metal stays its historical "advisory limits
     * only" mode — limits drive the scaler's per-machine cap math but no
     * cgroup is created.
     *
     * Linux-only. On macOS / Windows hosts the option is silently a no-op
     * (`systemd-run` does not exist), with a one-time startup warning.
     */
    enforceCgroups?: boolean;
}
export declare class BareMetalScalerBackend implements ScalerBackend {
    readonly type: "bare-metal";
    readonly spawnsOnLocalHost = true;
    readonly logsSource = "bare-metal";
    readonly maxAgents: number;
    private _labelSets;
    private readonly name;
    private readonly defaultResources?;
    private readonly tokenStore?;
    private readonly tokenTtlMs;
    private readonly roles;
    private readonly enforceCgroups;
    /** Tracks all managed agent processes */
    private readonly agents;
    /** LogCapture instances for each managed agent (keyed by ManagedAgent.id) */
    private readonly logCaptures;
    constructor(options: BareMetalScalerBackendOptions);
    private warnNetworkPolicy;
    /**
     * Declare required tools for a bare-metal scaler entry.
     *
     * - Every label set's `binaryPath` must be an executable file on disk.
     * - If `KICI_SANDBOX=true` will be forwarded to spawned agents (either via
     *   the orchestrator's `KICI_AGENT_ENV_KICI_SANDBOX=true` env var or via a
     *   label set's `env.KICI_SANDBOX=true` in scalers.yaml), then `bwrap` must
     *   be available on PATH so the agent can actually wrap workflow runners.
     *
     *   This check runs at orchestrator startup so misconfiguration fails
     *   fast with a clear error instead of crashing every job at dispatch
     *   time. On macOS and Windows (where bwrap does not exist) any attempt
     *   to enable KICI_SANDBOX will be rejected here.
     */
    static getRequiredTools(entry: ScalerEntry): ToolRequirement[];
    get labelSets(): LabelSetConfig[];
    getActiveCount(): number;
    spawn(labelSet: string[], agentId: string, orchestratorUrl: string, onEvent?: ScalerEventCallback, effectiveLimits?: EffectiveLimits): Promise<ManagedAgent>;
    getScalerContext(agentId: string): Record<string, unknown> | undefined;
    destroy(managedId: string): Promise<void>;
    /**
     * Get the LogCapture for a managed agent (used by ScalerManager for log forwarding).
     */
    getLogCapture(managedId: string): LogCapture | undefined;
    shutdownAll(): Promise<void>;
    reload(labelSets: LabelSetConfig[]): ValidationResult;
    /**
     * Build the (command, args) tuple used to spawn an agent process.
     *
     * Two modes:
     *   - Direct: returns (binaryPath, []) — the historical bare-metal flow.
     *     Used when enforceCgroups is false, the host is non-Linux, or the
     *     resolved limits carry no positive cpus/memBytes.
     *   - systemd-run scope: returns ('systemd-run', [...]) wrapping the
     *     binary in a transient `--user --scope --slice=kici-scaler` cgroup
     *     with `CPUQuota=` / `MemoryMax=` properties translated from the
     *     effective limits. The scope name embeds `agentId` so each agent is
     *     a separately-named transient unit (and `systemctl --user status
     *     kici-agent-<agentId>.scope` works).
     *
     * `CPUQuota` is expressed as a percent (1.0 cpus = 100%). `MemoryMax`
     * accepts a raw byte count.
     */
    private buildSpawnInvocation;
    /**
     * Wait for a process to exit within a timeout.
     * Returns true if the process exited, false if timed out.
     */
    private waitForExit;
}
//# sourceMappingURL=bare-metal-backend.d.ts.map