import { type DeviceNodeAnnouncement, type DeviceNodeProfile } from './device-capability-contract.js'; import { DeviceCapabilityService, type DeviceCapabilityPolicy } from './device-capability-service.js'; import { DeviceGrantStore } from './device-grants.js'; import { DeviceCaptureArtifactStore } from './device-capture-artifacts.js'; import { DeviceHousekeeper } from './device-housekeeping.js'; import { type DevicePostureConfigReader } from './device-posture-config.js'; import type { PermissionPromptDecision, PermissionPromptRequest } from '../permissions/prompt.js'; /** Metadata key a device node's pair request carries its announcement under. */ export declare const DEVICE_NODE_ANNOUNCEMENT_KEY = "deviceNode"; /** The peer fields this runtime reads. A real peer record satisfies it. */ export interface DevicePeerView { readonly id: string; readonly label: string; readonly kind: string; readonly platform?: string | undefined; readonly version?: string | undefined; readonly status: string; readonly capabilities: readonly string[]; readonly metadata: Record; } /** The work fields this runtime reads back off the queue. */ export interface DeviceWorkView { readonly id: string; readonly status: string; readonly result?: unknown | undefined; readonly error?: string | undefined; } /** * The two members of a distributed runtime manager this runtime needs. Declared * narrowly so a test can stand up a transport without a live peer process, and * so no surface has to hand over its whole runtime graph. */ export interface DevicePeerTransport { listPeers(kind?: string): readonly DevicePeerView[]; invokePeer(input: { readonly peerId: string; readonly command: string; readonly type?: string | undefined; readonly payload?: unknown | undefined; readonly actor?: string | undefined; readonly waitMs?: number | undefined; readonly timeoutMs?: number | undefined; }): Promise<{ work: DeviceWorkView; completed: boolean; }>; } /** The slice of the shared approval path the confirmation prompt rides. */ export interface DeviceApprovalBridge { requestApproval(input: { readonly request: PermissionPromptRequest; readonly sessionId?: string | undefined; readonly metadata?: Record | undefined; readonly timeoutMs?: number | undefined; }): Promise; } export interface DevicePostureRuntimeOptions { readonly transport: DevicePeerTransport; readonly approvals: DeviceApprovalBridge; readonly config: DevicePostureConfigReader; /** Directory the grants ledger, captures, and disclosure log live under. */ readonly stateDirectory: string; /** * Who the audit trail records for work items and grant revocations, e.g. * `tui:phone-tool`. A host that records something it is not makes the ledger * lie about where a decision was made. */ readonly actor?: string | undefined; /** The host's live session id, when it has one, for session-scoped prompts. */ readonly getSessionId?: (() => string | undefined) | undefined; } /** Everything a host (and its `phone` tool) needs, assembled from the runtime. */ export interface DevicePostureRuntime { readonly capabilities: DeviceCapabilityService; readonly grants: DeviceGrantStore; readonly artifacts: DeviceCaptureArtifactStore; readonly housekeeper: DeviceHousekeeper; /** The actor string this host records in the ledger. */ readonly actor: string; listNodes(): readonly DeviceNodeProfile[]; /** The posture in force right now, re-read from configuration. */ readPolicy(): DeviceCapabilityPolicy; /** Recovery sweep plus the periodic timer; call once during bootstrap. */ startHousekeeping(): Promise; stopHousekeeping(): void; } /** * Read a peer's device-node announcement out of its pairing metadata. * A peer without one is an ordinary peer, not a device node. */ export declare function readDeviceAnnouncement(peer: DevicePeerView): DeviceNodeAnnouncement | null; /** The paired device nodes a transport currently reports. */ export declare function listDeviceNodesFromTransport(transport: DevicePeerTransport): readonly DeviceNodeProfile[]; /** * Build the device feature for one host. Constructing this opens no connection, * starts no timer, and prompts nobody: call `startHousekeeping()` once the host * is up. * * Every policy is passed as a RESOLVER rather than a snapshot, so a `device.*` * change in the settings workspace governs the next request, the next grant, and * the next sweep without a restart. */ export declare function createDevicePostureRuntime(options: DevicePostureRuntimeOptions): DevicePostureRuntime; //# sourceMappingURL=device-posture-runtime.d.ts.map