@the-open-engine/zeroshot 6.5.0 → 6.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,227 @@
1
+ export type ArtifactRef = {
2
+ artifactId: string;
3
+ sha256: string;
4
+ byteLength: number;
5
+ mediaType: string;
6
+ typeId: string;
7
+ producer: { node: string; worker: string };
8
+ lineage: { generation: number; runId: string; attempt: number };
9
+ redaction: 'public' | 'internal' | 'confidential' | 'restricted';
10
+ };
11
+
12
+ type RequestBase = {
13
+ isolationProfile: string;
14
+ providerProfile: string;
15
+ };
16
+
17
+ export type LegacyShipRequest = RequestBase &
18
+ (
19
+ | { source: 'issue'; issue: string; prompt?: null; artifacts: [] }
20
+ | { source: 'prompt'; prompt: string; issue?: null; artifacts: [] }
21
+ | { source: 'artifact'; issue?: null; prompt?: null; artifacts: ArtifactRef[] }
22
+ );
23
+
24
+ export type LegacyShipResult = {
25
+ summary: string;
26
+ status: 'succeeded' | 'failed';
27
+ artifacts: ArtifactRef[];
28
+ };
29
+
30
+ export type LifecycleState =
31
+ | 'idle'
32
+ | 'starting'
33
+ | 'running'
34
+ | 'stopping'
35
+ | 'completed'
36
+ | 'failed'
37
+ | 'timed_out'
38
+ | 'stopped'
39
+ | 'malformed';
40
+
41
+ export type LifecycleStatus = {
42
+ state: LifecycleState;
43
+ clusterId: string | null;
44
+ sequence: number;
45
+ stopRequested: boolean;
46
+ terminal: boolean;
47
+ };
48
+
49
+ export type WorkerError =
50
+ | {
51
+ status: 'error';
52
+ code: 'timeout' | 'crash' | 'malformed' | 'refusal';
53
+ reason: 'declared_failure';
54
+ }
55
+ | {
56
+ status: 'error';
57
+ code: 'refusal';
58
+ reason: 'policy_denied' | 'interactive_input_required' | 'authentication_required';
59
+ }
60
+ | { status: 'error'; code: 'malformed'; reason: 'malformed_result' };
61
+
62
+ export type TerminalReceipt =
63
+ | { state: 'completed'; clusterId: string; finishedAt: number; result: LegacyShipResult }
64
+ | {
65
+ state: 'stopped';
66
+ clusterId: string;
67
+ finishedAt: number;
68
+ stop: { requested: true; effective: boolean; externalEffectsRolledBack: false };
69
+ }
70
+ | {
71
+ state: 'failed' | 'timed_out' | 'malformed';
72
+ clusterId: string;
73
+ finishedAt: number;
74
+ outcome: WorkerError;
75
+ };
76
+
77
+ export type LifecycleEvent = {
78
+ sequence: number;
79
+ state: Exclude<LifecycleState, 'idle'>;
80
+ at: number;
81
+ details?: unknown;
82
+ };
83
+
84
+ export type RunPlan = Readonly<{
85
+ isolation: 'worktree' | 'docker';
86
+ delivery: 'none' | 'pr' | 'ship';
87
+ autoMerge: boolean;
88
+ }>;
89
+
90
+ export type ExecutionBounds = Readonly<{
91
+ executionMs: number;
92
+ shutdownMs: number;
93
+ frameBytes: number;
94
+ }>;
95
+
96
+ export type ResolvedDeploymentProfile = Readonly<{
97
+ isolationProfile: string;
98
+ providerProfile: string;
99
+ plan: RunPlan;
100
+ deployment: Readonly<Record<string, unknown>>;
101
+ provider: Readonly<Record<string, unknown>>;
102
+ bounds: ExecutionBounds;
103
+ }>;
104
+
105
+ export type CancellationContext = Readonly<{ signal: AbortSignal }>;
106
+
107
+ export type CleanupFailure = Readonly<{
108
+ phase: 'profile_resolution' | 'artifact_staging' | 'receipt_collection';
109
+ kind: 'operation' | 'cleanup';
110
+ clusterId: string | null;
111
+ error: unknown;
112
+ }>;
113
+
114
+ export type IsolationWorkspace = Readonly<{
115
+ kind: 'worktree' | 'docker';
116
+ hostRoot: string;
117
+ runtimeRoot: string;
118
+ }>;
119
+
120
+ export interface DeploymentProfileRegistry {
121
+ readonly bounds?: ExecutionBounds;
122
+ resolve(
123
+ isolationProfile: string,
124
+ providerProfile: string,
125
+ context: CancellationContext
126
+ ): ResolvedDeploymentProfile | Promise<ResolvedDeploymentProfile>;
127
+ release?(profile: ResolvedDeploymentProfile, context: CancellationContext): void | Promise<void>;
128
+ }
129
+
130
+ export interface ArtifactResolver {
131
+ stage(
132
+ artifacts: readonly ArtifactRef[],
133
+ context: Readonly<{
134
+ clusterId: string;
135
+ profile: ResolvedDeploymentProfile;
136
+ isolation: IsolationWorkspace;
137
+ signal: AbortSignal;
138
+ }>
139
+ ): Readonly<Record<string, unknown>> | Promise<Readonly<Record<string, unknown>>>;
140
+ cleanup?(
141
+ manifest: Readonly<Record<string, unknown>>,
142
+ context: Readonly<{
143
+ clusterId: string;
144
+ profile: ResolvedDeploymentProfile;
145
+ isolation: IsolationWorkspace;
146
+ signal: AbortSignal;
147
+ }>
148
+ ): void | Promise<void>;
149
+ }
150
+
151
+ export interface ArtifactReceiptSink {
152
+ collect(
153
+ declared: readonly unknown[],
154
+ context: Readonly<{
155
+ clusterId: string;
156
+ profile: ResolvedDeploymentProfile;
157
+ signal: AbortSignal;
158
+ }>
159
+ ): readonly ArtifactRef[] | Promise<readonly ArtifactRef[]>;
160
+ cleanup?(
161
+ receipts: readonly ArtifactRef[],
162
+ context: Readonly<{
163
+ clusterId: string;
164
+ profile: ResolvedDeploymentProfile;
165
+ signal: AbortSignal;
166
+ }>
167
+ ): void | Promise<void>;
168
+ }
169
+
170
+ export type EngineEvent =
171
+ | { type: 'running' }
172
+ | ({ type: 'complete'; artifacts?: readonly unknown[] } & (
173
+ | { summary: string; result?: never }
174
+ | { result: LegacyShipResult; summary?: string }
175
+ ))
176
+ | ({ type: 'failed' } & Omit<WorkerError, 'status'>)
177
+ | { type: 'malformed' };
178
+
179
+ export interface EngineAdapter {
180
+ start(input: {
181
+ request: LegacyShipRequest;
182
+ profile: ResolvedDeploymentProfile;
183
+ prepareArtifacts?(isolation: IsolationWorkspace): Promise<Readonly<Record<string, unknown>>>;
184
+ clusterId: string;
185
+ onEvent(event: EngineEvent): void;
186
+ }):
187
+ | { clusterId?: string; artifactsStaged?: boolean }
188
+ | Promise<{ clusterId?: string; artifactsStaged?: boolean }>;
189
+ status?(): Readonly<Record<string, unknown>> | null;
190
+ stop(): { effective?: boolean } | Promise<{ effective?: boolean }>;
191
+ waitForCleanup?(): void | Promise<void>;
192
+ close?(): void | Promise<void>;
193
+ }
194
+
195
+ export type LegacyClusterWorkerDependencies = {
196
+ profileRegistry?: DeploymentProfileRegistry;
197
+ artifactResolver?: ArtifactResolver | ArtifactResolver['stage'];
198
+ artifactReceiptSink?: ArtifactReceiptSink | ArtifactReceiptSink['collect'];
199
+ engineAdapter?: EngineAdapter;
200
+ clock?: () => number;
201
+ timers?: {
202
+ setTimeout(callback: () => void, milliseconds: number): unknown;
203
+ clearTimeout(handle: unknown): void;
204
+ };
205
+ idFactory?: () => string;
206
+ cleanupFailureReporter?: (failure: CleanupFailure) => void | Promise<void>;
207
+ };
208
+
209
+ export interface LegacyClusterWorker {
210
+ start(request: LegacyShipRequest): Promise<LifecycleStatus>;
211
+ status(): LifecycleStatus;
212
+ events(): AsyncIterableIterator<LifecycleEvent>;
213
+ stop(): Promise<TerminalReceipt>;
214
+ result(): Promise<TerminalReceipt>;
215
+ }
216
+
217
+ export function createLegacyClusterWorker(
218
+ dependencies?: LegacyClusterWorkerDependencies
219
+ ): LegacyClusterWorker;
220
+
221
+ export function createDeploymentProfileRegistry(options?: {
222
+ isolationProfiles?: Readonly<Record<string, Readonly<Record<string, unknown>>>>;
223
+ providerProfiles?: Readonly<Record<string, Readonly<Record<string, unknown>>>>;
224
+ bounds?: Partial<ExecutionBounds>;
225
+ }): DeploymentProfileRegistry;
226
+
227
+ export function createCurrentEngineAdapter(options?: object): EngineAdapter;
@@ -0,0 +1,294 @@
1
+ 'use strict';
2
+
3
+ const { validateLegacyShipRequest } = require('./contracts');
4
+ const { createCurrentEngineAdapter } = require('./engine-adapter');
5
+ const { cloneJson, deepFreeze } = require('./object-utils');
6
+ const { createDeploymentProfileRegistry, DEFAULT_BOUNDS } = require('./profiles');
7
+ const {
8
+ CANCELLED,
9
+ assertIsolatedProfile,
10
+ createArtifactPreparation,
11
+ errorOutcome,
12
+ resolveRuntimeDependencies,
13
+ runCancellable,
14
+ } = require('./runtime-support');
15
+ const { releaseEngine, stopEngine } = require('./runtime-engine');
16
+ const { LegacyWorkerStateMachine } = require('./state-machine');
17
+ const { createTerminalNormalizer } = require('./terminal-normalizer');
18
+ const { createWorkerFacade } = require('./worker-internals');
19
+
20
+ class LegacyClusterWorkerRuntime {
21
+ constructor(dependencies) {
22
+ Object.assign(this, resolveRuntimeDependencies(dependencies));
23
+ this.machine = new LegacyWorkerStateMachine({ clock: this.clock });
24
+ this.startClaimed = false;
25
+ this.profile = null;
26
+ this.timeoutHandle = null;
27
+ this.timeoutGeneration = 0;
28
+ this.executionStartedAt = null;
29
+ this.terminalAuthority = null;
30
+ this.engineStartAttempted = false;
31
+ this.engineStopPromise = null;
32
+ this.engineReleasePromise = null;
33
+ this.preparationController = new AbortController();
34
+ this.terminalClaimed = new Promise((resolve) => {
35
+ this.resolveTerminalClaimed = resolve;
36
+ });
37
+ this.onEngineEvent = createTerminalNormalizer({
38
+ machine: this.machine,
39
+ clock: this.clock,
40
+ artifactReceiptSink: this.artifactReceiptSink,
41
+ getProfile: () => this.profile,
42
+ claimTerminalAuthority: (authority) => this.claimTerminalAuthority(authority),
43
+ failureReceipt: (state, code, reason) => this.failureReceipt(state, code, reason),
44
+ isTerminal: () => this.terminalAuthority !== null || Boolean(this.machine.terminalReceipt),
45
+ terminalClaimed: this.terminalClaimed,
46
+ signal: this.preparationController.signal,
47
+ cancelled: CANCELLED,
48
+ cleanupFailureReporter: this.cleanupFailureReporter,
49
+ });
50
+ }
51
+ clearExecutionTimeout() {
52
+ this.timeoutGeneration += 1;
53
+ if (this.timeoutHandle !== null) {
54
+ try {
55
+ this.timers.clearTimeout(this.timeoutHandle);
56
+ } catch {
57
+ // The generation guard still makes a stale callback inert.
58
+ }
59
+ }
60
+ this.timeoutHandle = null;
61
+ }
62
+ armExecutionTimeout(milliseconds) {
63
+ this.clearExecutionTimeout();
64
+ const generation = this.timeoutGeneration;
65
+ const elapsed = Math.max(0, this.clock() - this.executionStartedAt);
66
+ const remaining = Math.max(0, milliseconds - elapsed);
67
+ this.timeoutHandle = this.timers.setTimeout(() => {
68
+ if (generation !== this.timeoutGeneration) return;
69
+ this.timeoutHandle = null;
70
+ if (this.claimTerminalAuthority('timeout')) {
71
+ this.machine.terminal(this.failureReceipt('timed_out', 'timeout', 'declared_failure'));
72
+ if (this.engineStartAttempted) this.stopEngine().catch(() => undefined);
73
+ }
74
+ }, remaining);
75
+ }
76
+ initialExecutionBound() {
77
+ const milliseconds =
78
+ this.profile?.bounds.executionMs ?? this.profileRegistry?.bounds?.executionMs;
79
+ return Number.isSafeInteger(milliseconds) && milliseconds > 0
80
+ ? milliseconds
81
+ : DEFAULT_BOUNDS.executionMs;
82
+ }
83
+ cancelPreparation() {
84
+ this.preparationController.abort();
85
+ }
86
+ racePreparation(value, cleanup) {
87
+ return runCancellable(value, {
88
+ signal: this.preparationController.signal,
89
+ cleanup,
90
+ reportFailure: this.cleanupFailureReporter,
91
+ failureContext: {
92
+ phase: 'profile_resolution',
93
+ clusterId: this.machine.clusterId,
94
+ },
95
+ });
96
+ }
97
+ failureReceipt(state, code, reason) {
98
+ return {
99
+ state,
100
+ clusterId: this.machine.clusterId,
101
+ finishedAt: this.clock(),
102
+ outcome: errorOutcome(code, reason),
103
+ };
104
+ }
105
+ claimTerminalAuthority(authority) {
106
+ if (this.terminalAuthority !== null || this.machine.terminalReceipt) return false;
107
+ this.terminalAuthority = authority;
108
+ this.clearExecutionTimeout();
109
+ this.cancelPreparation();
110
+ this.resolveTerminalClaimed(CANCELLED);
111
+ return true;
112
+ }
113
+ failEngineStatus() {
114
+ if (this.claimTerminalAuthority('engine:status')) {
115
+ this.machine.terminal(this.failureReceipt('failed', 'crash', 'declared_failure'));
116
+ }
117
+ }
118
+ async prepareStart(request, clusterId, profileResolution) {
119
+ if (!this.profile) {
120
+ const profileContext = Object.freeze({ signal: this.preparationController.signal });
121
+ const resolvedProfile = await this.racePreparation(profileResolution, (profile) =>
122
+ this.profileRegistry.release?.(profile, profileContext)
123
+ );
124
+ if (resolvedProfile === CANCELLED) return CANCELLED;
125
+ this.profile = assertIsolatedProfile(resolvedProfile, request);
126
+ }
127
+ this.armExecutionTimeout(this.profile.bounds.executionMs);
128
+ if (this.terminalAuthority !== null) return CANCELLED;
129
+ return { clusterId };
130
+ }
131
+ async startEngine(request, clusterId) {
132
+ this.engineStartAttempted = true;
133
+ try {
134
+ const prepareArtifacts =
135
+ request.source === 'artifact'
136
+ ? createArtifactPreparation({
137
+ resolver: this.artifactResolver,
138
+ artifacts: request.artifacts,
139
+ clusterId,
140
+ getProfile: () => this.profile,
141
+ signal: this.preparationController.signal,
142
+ reportFailure: this.cleanupFailureReporter,
143
+ })
144
+ : null;
145
+ const engineStart = Promise.resolve(
146
+ this.engineAdapter.start({
147
+ request,
148
+ profile: this.profile,
149
+ ...(prepareArtifacts ? { prepareArtifacts } : {}),
150
+ clusterId,
151
+ onEvent: this.onEngineEvent,
152
+ })
153
+ );
154
+ const resource = await Promise.race([engineStart, this.terminalClaimed]);
155
+ if (resource === CANCELLED) {
156
+ if (!this.machine.terminalReceipt) await this.machine.result();
157
+ return this.machine.status();
158
+ }
159
+ if (resource?.clusterId && resource.clusterId !== clusterId) {
160
+ throw new Error('Engine allocated a cluster with a different id');
161
+ }
162
+ if (request.source === 'artifact' && resource?.artifactsStaged !== true) {
163
+ throw new Error('Engine started without staging artifact input');
164
+ }
165
+ if (this.machine.state === 'starting') this.machine.transition('running');
166
+ return this.machine.status();
167
+ } catch (error) {
168
+ if (this.claimTerminalAuthority('engine:start')) {
169
+ this.machine.terminal(this.failureReceipt('failed', 'crash', 'declared_failure'));
170
+ }
171
+ await this.stopEngine();
172
+ if (this.terminalAuthority !== 'engine:start' && !this.machine.terminalReceipt) {
173
+ await this.machine.result();
174
+ return this.machine.status();
175
+ }
176
+ throw error;
177
+ }
178
+ }
179
+ beginLifecycle() {
180
+ const clusterId = this.idFactory();
181
+ if (typeof clusterId !== 'string' || !clusterId) {
182
+ throw new Error('idFactory returned invalid id');
183
+ }
184
+ this.machine.setClusterId(clusterId);
185
+ this.machine.transition('starting');
186
+ this.executionStartedAt = this.clock();
187
+ this.armExecutionTimeout(this.initialExecutionBound());
188
+ return clusterId;
189
+ }
190
+ async start(request) {
191
+ if (this.startClaimed) throw new Error('Worker facade permits exactly one start');
192
+ const requestSnapshot = deepFreeze(cloneJson(request));
193
+ validateLegacyShipRequest(requestSnapshot);
194
+ if (requestSnapshot.source === 'artifact' && !this.artifactResolver) {
195
+ throw new Error('ArtifactResolver is required for artifact input');
196
+ }
197
+ // Claim synchronously so concurrent calls cannot allocate two resources.
198
+ this.startClaimed = true;
199
+ let clusterId;
200
+ try {
201
+ const profileResolution = this.profileRegistry.resolve(
202
+ requestSnapshot.isolationProfile,
203
+ requestSnapshot.providerProfile,
204
+ Object.freeze({ signal: this.preparationController.signal })
205
+ );
206
+ if (!profileResolution || typeof profileResolution.then !== 'function') {
207
+ this.profile = assertIsolatedProfile(profileResolution, requestSnapshot);
208
+ }
209
+ clusterId = this.beginLifecycle();
210
+ const prepared = await this.prepareStart(requestSnapshot, clusterId, profileResolution);
211
+ if (prepared === CANCELLED) return this.machine.status();
212
+ return this.startEngine(requestSnapshot, clusterId);
213
+ } catch (error) {
214
+ if (this.terminalAuthority !== null) {
215
+ if (!this.machine.terminalReceipt) await this.machine.result();
216
+ return this.machine.status();
217
+ }
218
+ if (!this.machine.clusterId) {
219
+ this.startClaimed = false;
220
+ throw error;
221
+ }
222
+ if (this.machine.clusterId && this.claimTerminalAuthority('engine:start-setup')) {
223
+ this.machine.terminal(this.failureReceipt('failed', 'crash', 'declared_failure'));
224
+ }
225
+ throw error;
226
+ }
227
+ }
228
+ status() {
229
+ if (
230
+ this.engineStartAttempted &&
231
+ this.machine.clusterId &&
232
+ !this.machine.terminalReceipt &&
233
+ typeof this.engineAdapter.status === 'function'
234
+ ) {
235
+ try {
236
+ const diagnostic = this.engineAdapter.status();
237
+ if (diagnostic && typeof diagnostic.then === 'function') {
238
+ diagnostic.then(undefined, () => this.failEngineStatus());
239
+ throw new TypeError('EngineAdapter.status() must return synchronously');
240
+ }
241
+ } catch (error) {
242
+ this.failEngineStatus();
243
+ if (!this.machine.terminalReceipt) throw error;
244
+ }
245
+ }
246
+ return this.machine.status();
247
+ }
248
+ events() {
249
+ return this.machine.events();
250
+ }
251
+ stopEngine() {
252
+ return stopEngine(this);
253
+ }
254
+ async releaseEngine() {
255
+ await releaseEngine(this);
256
+ }
257
+ async stop() {
258
+ if (!this.startClaimed) throw new Error('Worker has not started');
259
+ if (this.machine.terminalReceipt) {
260
+ const cleanupEffective = this.engineStopPromise ? await this.engineStopPromise : true;
261
+ if (cleanupEffective) await this.releaseEngine();
262
+ return this.machine.terminalReceipt;
263
+ }
264
+ if (!this.claimTerminalAuthority('stop')) return this.machine.result();
265
+ this.machine.requestStop();
266
+ const effective = this.engineStartAttempted ? await this.stopEngine() : true;
267
+ this.machine.terminal({
268
+ state: 'stopped',
269
+ clusterId: this.machine.clusterId,
270
+ finishedAt: this.clock(),
271
+ stop: {
272
+ requested: true,
273
+ effective,
274
+ externalEffectsRolledBack: false,
275
+ },
276
+ });
277
+ if (effective) await this.releaseEngine();
278
+ return this.machine.terminalReceipt;
279
+ }
280
+ result() {
281
+ if (!this.startClaimed) throw new Error('Worker has not started');
282
+ return this.machine.result();
283
+ }
284
+ }
285
+
286
+ function createLegacyClusterWorker(dependencies = {}) {
287
+ return createWorkerFacade(new LegacyClusterWorkerRuntime(dependencies));
288
+ }
289
+
290
+ module.exports = {
291
+ createLegacyClusterWorker,
292
+ createDeploymentProfileRegistry,
293
+ createCurrentEngineAdapter,
294
+ };
@@ -0,0 +1,17 @@
1
+ 'use strict';
2
+
3
+ function deepFreeze(value) {
4
+ if (!value || typeof value !== 'object') return value;
5
+ for (const child of Object.values(value)) deepFreeze(child);
6
+ return Object.isFrozen(value) ? value : Object.freeze(value);
7
+ }
8
+
9
+ function cloneJson(value) {
10
+ if (Array.isArray(value)) return value.map(cloneJson);
11
+ if (value && typeof value === 'object') {
12
+ return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, cloneJson(child)]));
13
+ }
14
+ return value;
15
+ }
16
+
17
+ module.exports = { cloneJson, deepFreeze };
@@ -0,0 +1,37 @@
1
+ 'use strict';
2
+
3
+ const util = require('node:util');
4
+
5
+ function redirectConsoleToStderr() {
6
+ console.log = (...args) => process.stderr.write(`${util.format(...args)}\n`);
7
+ console.info = console.log;
8
+ console.debug = console.log;
9
+ }
10
+
11
+ function bindProcessLifecycle(runtime) {
12
+ let closing = null;
13
+ const closeAndRelease = () => {
14
+ closing ||= Promise.resolve()
15
+ .then(() => runtime.close())
16
+ .then(
17
+ () => {
18
+ process.exitCode = 0;
19
+ process.exit(0);
20
+ },
21
+ (error) => {
22
+ process.stderr.write(`cluster-worker shutdown failed: ${error.message}\n`);
23
+ process.exitCode = 1;
24
+ process.exit(1);
25
+ }
26
+ );
27
+ };
28
+ const closeFromSignal = () => {
29
+ process.stdin.pause();
30
+ process.stdin.destroy();
31
+ closeAndRelease();
32
+ };
33
+ process.stdin.once('end', closeAndRelease);
34
+ for (const signal of ['SIGINT', 'SIGTERM']) process.once(signal, closeFromSignal);
35
+ }
36
+
37
+ module.exports = { bindProcessLifecycle, redirectConsoleToStderr };
@@ -0,0 +1,81 @@
1
+ 'use strict';
2
+
3
+ const { resolveRunPlan } = require('../run-plan');
4
+ const { deepFreeze } = require('./object-utils');
5
+
6
+ const DEFAULT_BOUNDS = Object.freeze({
7
+ executionMs: 60 * 60 * 1000,
8
+ shutdownMs: 30 * 1000,
9
+ frameBytes: 64 * 1024,
10
+ });
11
+
12
+ const DEFAULT_ISOLATION_PROFILES = Object.freeze({
13
+ 'isolation.worktree@1': Object.freeze({ worktree: true }),
14
+ 'isolation.docker@1': Object.freeze({ docker: true }),
15
+ 'isolation.pr@1': Object.freeze({ pr: true }),
16
+ 'isolation.ship@1': Object.freeze({ ship: true }),
17
+ });
18
+
19
+ const DEFAULT_PROVIDER_PROFILES = Object.freeze({
20
+ 'provider.default@1': Object.freeze({
21
+ configName: 'conductor-bootstrap',
22
+ providerOverride: null,
23
+ settings: Object.freeze({}),
24
+ }),
25
+ });
26
+
27
+ function own(map, key) {
28
+ return Object.prototype.hasOwnProperty.call(map, key) ? map[key] : null;
29
+ }
30
+
31
+ function validateBounds(bounds) {
32
+ for (const name of ['executionMs', 'shutdownMs', 'frameBytes']) {
33
+ if (!Number.isSafeInteger(bounds[name]) || bounds[name] <= 0) {
34
+ throw new Error(`Deployment bound ${name} must be a positive safe integer`);
35
+ }
36
+ }
37
+ }
38
+
39
+ function createDeploymentProfileRegistry(options = {}) {
40
+ const isolationProfiles = options.isolationProfiles || DEFAULT_ISOLATION_PROFILES;
41
+ const providerProfiles = options.providerProfiles || DEFAULT_PROVIDER_PROFILES;
42
+ const defaultBounds = { ...DEFAULT_BOUNDS, ...(options.bounds || {}) };
43
+ validateBounds(defaultBounds);
44
+ const bounds = deepFreeze(defaultBounds);
45
+
46
+ return Object.freeze({
47
+ bounds,
48
+ resolve(isolationHandle, providerHandle) {
49
+ const deployment = own(isolationProfiles, isolationHandle);
50
+ if (!deployment) throw new Error(`Unknown isolation profile: ${String(isolationHandle)}`);
51
+ const provider = own(providerProfiles, providerHandle);
52
+ if (!provider) throw new Error(`Unknown provider profile: ${String(providerHandle)}`);
53
+
54
+ const plan = resolveRunPlan(deployment);
55
+ if (plan.isolation !== 'worktree' && plan.isolation !== 'docker') {
56
+ throw new Error(`Isolation profile ${isolationHandle} resolves to non-isolated execution`);
57
+ }
58
+ const resolvedBounds = {
59
+ ...defaultBounds,
60
+ ...(deployment.bounds || {}),
61
+ ...(provider.bounds || {}),
62
+ };
63
+ validateBounds(resolvedBounds);
64
+ return deepFreeze({
65
+ isolationProfile: isolationHandle,
66
+ providerProfile: providerHandle,
67
+ plan,
68
+ deployment: { ...deployment },
69
+ provider: { ...provider },
70
+ bounds: resolvedBounds,
71
+ });
72
+ },
73
+ });
74
+ }
75
+
76
+ module.exports = {
77
+ DEFAULT_BOUNDS,
78
+ DEFAULT_ISOLATION_PROFILES,
79
+ DEFAULT_PROVIDER_PROFILES,
80
+ createDeploymentProfileRegistry,
81
+ };