/** * Worker Control Service (2.13.0). * * The durable daemon boundary that composes the existing primitives into a * long-lived worker loop. It NEVER re-implements executor identity, assignment * claim, execution fencing, mission lifecycle, evidence, or verification — it * consumes them: * * - ExecutorControlService → worker identity + incarnation + heartbeat. * - AssignmentControlService → discovery + claim + execution + completion. * - DurableMissionCoordinator → crash reconciliation + stale-owner interrupt. * - ProcessMissionExecutor → the existing local child-resume execution path. * - buildAcceptanceCriteriaVerifier → deterministic completion promotion. * * Critical invariant (Jensen 3.0): logical agent concurrency != inference * concurrency. This worker owns an Assignment for its full logical lifetime, but * never reserves a Qwen inference slot for that lifetime. Inference is acquired * only while the child execution actually performs an inference request; the * future Shared Inference Scheduler will park/rehydrate the logical execution * (RUNNING → WAITING(INFERENCE) → RUNNING) without touching worker identity. */ import type { AssignmentControlService, BuildAssignedExecutor, BuildAssignedResumeLaunch } from "../assignment/assignment-control-service.js"; import type { ExecutorControlService, ExecutorRuntimeProof } from "../executor-registry/index.js"; import type { DurableMissionStore } from "../mission-domain/durable-store.js"; import type { ProcessMissionVerifier } from "../mission-domain/process-mission-executor.js"; import { type WorkerDaemonState, type WorkerRecoveryReport, type WorkerRunOutcome, type WorkerStartOutcome, type WorkerStatus, type WorkerSummary } from "./worker-types.js"; export interface WorkerControlServiceOptions { /** The logical executor this worker serves (workerId is derived). */ executorId: string; executors: ExecutorControlService; assignments: AssignmentControlService; missions: DurableMissionStore; /** Maps a durable child mission to the concrete local child CLI launch. */ buildResumeLaunch: BuildAssignedResumeLaunch; /** * Optional executor builder for a REMOTE executor. When set, the worker uses * it instead of the local `ProcessMissionExecutor` path. Built per-worker by * the CLI when the executor is bound to a remote target. */ buildExecutor?: BuildAssignedExecutor; /** * Optional verifier that promotes a clean exit-0 execution to SUCCEEDED. * When omitted, the worker builds one from the mission's declared acceptance * criteria (`buildAcceptanceCriteriaVerifier`). A mission with no verifiable * criteria therefore stays PARTIAL (unverified), never fabricated SUCCEEDED. */ verifier?: ProcessMissionVerifier; /** Poll cadence for assignment discovery (default 1000ms). */ pollMs?: number; /** Heartbeat cadence for worker liveness (default 3000ms). */ heartbeatMs?: number; /** Heartbeat expiry window (default from ExecutorControlService). */ expiryMs?: number; /** Lease duration used for child execution (default 30 min). */ leaseDurationMs?: number; now?: () => number; /** Worker instance id factory (default host+UUID; never a PID). */ workerInstanceIdFactory?: () => string; } export declare class WorkerControlService { private readonly _executorId; private readonly _workerId; private readonly _executors; private readonly _assignments; private readonly _missions; private readonly _buildResumeLaunch; private readonly _buildExecutor?; private readonly _verifier?; private readonly _pollMs; private readonly _heartbeatMs; private readonly _expiryMs?; private readonly _leaseDurationMs?; private readonly _now; private readonly _workerInstanceIdFactory; private _proof?; private _identity?; private _daemonState; private _heartbeatTimer?; private _pollTimer?; private _running; private _currentAbort?; private _inFlight?; private _lastError?; constructor(options: WorkerControlServiceOptions); get executorId(): string; get workerId(): string; get daemonState(): WorkerDaemonState; get proof(): ExecutorRuntimeProof | undefined; /** * Register (idempotent) + activate a runtime incarnation + begin heartbeat * and polling. Exactly one worker runtime can be live per executor at a time; * a second concurrent `start()` for the same executor fails closed with * EXECUTOR_ALREADY_ACTIVE (the duplicate-daemon single-owner fence). */ start(options?: { reconcile?: boolean; polling?: boolean; }): Promise; /** * Graceful shutdown: stop accepting work, stop heartbeats, abort any * in-flight execution honestly (the fenced child path persists CANCELLED, * never a fabricated success), and deactivate the runtime incarnation. */ stop(reason?: string): Promise; /** * One discovery → claim → execute cycle. Deterministic ordering by * `createdAtMs` (then assignmentId). `--once` callers use this directly; * the daemon poll loop invokes it while idle. Never runs two executions * concurrently (initial concurrency policy = serial). */ runOnce(): Promise; private _runOnceImpl; /** Durable read model of this worker's identity, liveness, and current work. */ status(): Promise; /** * Conservative restart reconciliation. Runs the durable-store recovery * (expired leases → INTERRUPTED) and additionally revokes still-live leases * left behind by a prior worker incarnation of THIS executor (identified via * stale assignment `executionOwnerIdentity`). Never auto-runs side-effectful * work and never fabricates success. */ reconcile(): Promise; private _activate; private _activateRuntime; private _heartbeat; private _poll; private _eligibleAssignments; private _verifierFor; private _currentAssignment; private _currentExecution; private _activityFor; } export declare function listWorkers(options: { executors: ExecutorControlService; assignments: AssignmentControlService; missions: DurableMissionStore; }): Promise<{ entries: WorkerSummary[]; corrupt: { executorId: string; diagnostic: string; }[]; }>; //# sourceMappingURL=worker-control-service.d.ts.map