/**
 * Placement primitives for capability-routed spawns. The
 * `RelaycastMessagingClient` owns the queue/reconcile state machine; this
 * module holds the stateless pieces it builds on: the error type the queue
 * throws, the selection result shape, and the helpers that translate a chosen
 * placement into an `actions.invoke` payload.
 */
import type { RelayNode } from './types.js';
export type PlacementReconcileReason = 'no_eligible_node' | 'target_offline' | 'unmapped_repo';
export type PlacementSelection = {
    node: RelayNode;
    message?: never;
    hardFail?: never;
    reason?: never;
    reconcileReason?: never;
} | {
    node?: never;
    message: string;
    hardFail: true;
    reason: 'capability_mismatch';
    reconcileReason: PlacementReconcileReason;
} | {
    node?: never;
    message: string;
    hardFail?: false;
    reason?: never;
    reconcileReason: PlacementReconcileReason;
};
export declare class RelayPlacementError extends Error {
    readonly code: 'capability_mismatch' | 'placement_queue_full' | 'placement_ttl_expired' | 'unmapped_repo';
    readonly capability: string;
    readonly node?: string;
    readonly repo?: string;
    readonly attempts: number;
    constructor(code: RelayPlacementError['code'], message: string, context: {
        capability: string;
        node?: string;
        repo?: string;
        attempts: number;
    });
}
export declare function nonEmptyPlacement(value: string, label: string): string;
export declare function placementActionName(capability: string): string;
export declare function placementActionInput(input: Record<string, unknown> | undefined, placement: {
    capability: string;
    node: string;
    repo?: string;
    ttlMs: number;
}): Record<string, unknown>;
export declare function delay(ms: number): Promise<void>;
//# sourceMappingURL=relaycast-placement.d.ts.map