@cat-factory/orchestration 0.123.4 → 0.123.6
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.
- package/dist/modules/execution/AgentContextBuilder.d.ts.map +1 -1
- package/dist/modules/execution/AgentContextBuilder.js +14 -13
- package/dist/modules/execution/AgentContextBuilder.js.map +1 -1
- package/dist/modules/execution/DeployerStepController.d.ts +185 -0
- package/dist/modules/execution/DeployerStepController.d.ts.map +1 -0
- package/dist/modules/execution/DeployerStepController.js +670 -0
- package/dist/modules/execution/DeployerStepController.js.map +1 -0
- package/dist/modules/execution/ExecutionService.d.ts +8 -211
- package/dist/modules/execution/ExecutionService.d.ts.map +1 -1
- package/dist/modules/execution/ExecutionService.js +59 -805
- package/dist/modules/execution/ExecutionService.js.map +1 -1
- package/dist/modules/execution/FollowUpGateController.d.ts +104 -0
- package/dist/modules/execution/FollowUpGateController.d.ts.map +1 -0
- package/dist/modules/execution/FollowUpGateController.js +317 -0
- package/dist/modules/execution/FollowUpGateController.js.map +1 -0
- package/dist/modules/execution/RunAdmission.d.ts +204 -0
- package/dist/modules/execution/RunAdmission.d.ts.map +1 -0
- package/dist/modules/execution/RunAdmission.js +571 -0
- package/dist/modules/execution/RunAdmission.js.map +1 -0
- package/dist/modules/execution/RunDispatcher.d.ts +24 -196
- package/dist/modules/execution/RunDispatcher.d.ts.map +1 -1
- package/dist/modules/execution/RunDispatcher.js +70 -929
- package/dist/modules/execution/RunDispatcher.js.map +1 -1
- package/dist/modules/execution/review-kinds.d.ts +41 -0
- package/dist/modules/execution/review-kinds.d.ts.map +1 -0
- package/dist/modules/execution/review-kinds.js +241 -0
- package/dist/modules/execution/review-kinds.js.map +1 -0
- package/package.json +8 -8
|
@@ -0,0 +1,571 @@
|
|
|
1
|
+
import { ConflictError, isAllowedByFamilyPolicy, isModelUsable, isModelUsableInline, resolveModelRef, subscriptionOptionFor, } from '@cat-factory/kernel';
|
|
2
|
+
import { frameAllowsVisualPipeline, frameProfile, isLocalRunner, pipelineHasVisualStep, } from '@cat-factory/contracts';
|
|
3
|
+
import { BINARY_STORAGE_TRAIT, hasTrait, isInlineModelStep } from '@cat-factory/agents';
|
|
4
|
+
import { validatePipelineShape } from '../pipelines/pipelineShape.js';
|
|
5
|
+
import { assertInitiativeShapeAllowed } from '../initiative/initiative.logic.js';
|
|
6
|
+
import { isTesterKind } from './ci.logic.js';
|
|
7
|
+
import { decideTesterInfra, ENV_CONSUMER_KINDS, needsDeployerBeforeConsumer, TESTER_INFRA_MESSAGES, } from './tester-infra.logic.js';
|
|
8
|
+
import { decideDeployerConfig, deployerServiceConfigIssues, hasEnabledDeployerStep, } from './deployer.logic.js';
|
|
9
|
+
import { hasLiveServiceBinding, hasServiceBinding } from './frontend-infra.logic.js';
|
|
10
|
+
import { dependenciesMet, unmetDependencies } from '../board/board.logic.js';
|
|
11
|
+
/**
|
|
12
|
+
* The run ADMISSION preflights — every config/resource precondition a run must satisfy
|
|
13
|
+
* before it is allowed to START, RETRY or RESTART, extracted out of `ExecutionService`
|
|
14
|
+
* so the engine's public lifecycle methods stay readable while the guard family grows.
|
|
15
|
+
* All checks are read-only and run BEFORE any side effects, each throwing an actionable
|
|
16
|
+
* {@link ConflictError}. The shared entry point is {@link assertRunnable}; the start-only
|
|
17
|
+
* concurrency/dependency gates ({@link assertWithinTaskLimit}, {@link assertDependenciesMet})
|
|
18
|
+
* are separate because a retry/restart deliberately skips them.
|
|
19
|
+
*/
|
|
20
|
+
export class RunAdmission {
|
|
21
|
+
workspaceRepository;
|
|
22
|
+
blockRepository;
|
|
23
|
+
executionRepository;
|
|
24
|
+
contextBuilder;
|
|
25
|
+
agentKindRegistry;
|
|
26
|
+
spend;
|
|
27
|
+
environmentProvisioning;
|
|
28
|
+
workspaceSettingsService;
|
|
29
|
+
resolveBinaryArtifactStore;
|
|
30
|
+
resolveProviderCapabilities;
|
|
31
|
+
inlineHarnessRef;
|
|
32
|
+
resolveWorkspaceModelDefault;
|
|
33
|
+
assertAgentBackendConfigured;
|
|
34
|
+
constructor(deps) {
|
|
35
|
+
this.workspaceRepository = deps.workspaceRepository;
|
|
36
|
+
this.blockRepository = deps.blockRepository;
|
|
37
|
+
this.executionRepository = deps.executionRepository;
|
|
38
|
+
this.contextBuilder = deps.contextBuilder;
|
|
39
|
+
this.agentKindRegistry = deps.agentKindRegistry;
|
|
40
|
+
this.spend = deps.spend;
|
|
41
|
+
this.environmentProvisioning = deps.environmentProvisioning;
|
|
42
|
+
this.workspaceSettingsService = deps.workspaceSettingsService;
|
|
43
|
+
this.resolveBinaryArtifactStore = deps.resolveBinaryArtifactStore;
|
|
44
|
+
this.resolveProviderCapabilities = deps.resolveProviderCapabilities;
|
|
45
|
+
this.inlineHarnessRef = deps.inlineHarnessRef;
|
|
46
|
+
this.resolveWorkspaceModelDefault = deps.resolveWorkspaceModelDefault;
|
|
47
|
+
this.assertAgentBackendConfigured = deps.assertAgentBackendConfigured;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* The config/resource preconditions a run must satisfy to START, RETRY **or** RESTART:
|
|
51
|
+
* everything that depends on the workspace environment + the steps being run, and NOT on
|
|
52
|
+
* whether this is a fresh run or a replacement. All three entry points call this so they
|
|
53
|
+
* can't drift — a guard added to one but silently missing from the other is exactly how a
|
|
54
|
+
* subscription-only preset slipped past retry and failed mid-run against the routing default.
|
|
55
|
+
* All checks are read-only and run BEFORE any side effects, each throwing an actionable
|
|
56
|
+
* {@link ConflictError}.
|
|
57
|
+
*
|
|
58
|
+
* The `shape` is the effective chain that will run, NOT the current pipeline definition: a
|
|
59
|
+
* fresh start passes the pipeline, while a retry/restart passes the STORED steps (via
|
|
60
|
+
* {@link runnableShapeOf}) so the guard validates exactly what re-executes — a pipeline
|
|
61
|
+
* edited out of band since the run started can't falsely refuse (or silently skip a check
|
|
62
|
+
* for) a step that isn't actually being re-driven.
|
|
63
|
+
*
|
|
64
|
+
* The concurrency (task-limit) and dependency gates are deliberately NOT here — they are
|
|
65
|
+
* start-only (a retry replaces the failed run rather than adding a new concurrent one, and a
|
|
66
|
+
* re-drive of an already-started task isn't re-gated on its dependencies).
|
|
67
|
+
*/
|
|
68
|
+
async assertRunnable(workspaceId, block, shape, initiatedBy) {
|
|
69
|
+
// Reject a structurally-invalid chain (a misplaced companion or estimate-gating without a
|
|
70
|
+
// preceding task-estimator). The builder also rejects these at save, but a pipeline can
|
|
71
|
+
// become invalid out of band.
|
|
72
|
+
validatePipelineShape(shape);
|
|
73
|
+
// The Initiative Planning kinds run ONLY on an `initiative`-level block, and an
|
|
74
|
+
// initiative block accepts ONLY such a chain — bidirectional, and here in the shared
|
|
75
|
+
// guard so start/retry/restart can't drift on it.
|
|
76
|
+
assertInitiativeShapeAllowed(block, shape.agentKinds);
|
|
77
|
+
// A chain with visual steps (`tester-ui` / `visual-confirmation`) needs a UI to exercise:
|
|
78
|
+
// it can only run on a `frontend` frame or a frame a frontend links to — else a `tester-ui`
|
|
79
|
+
// step has no app to drive.
|
|
80
|
+
await this.assertPipelineFrameTypeAllowed(workspaceId, block, shape.agentKinds);
|
|
81
|
+
// A chain with a Tester needs the service's declared provisioning to be runnable
|
|
82
|
+
// (`infraless`/none = no infra; `docker-compose`/`kubernetes`/`custom` = a workspace handler).
|
|
83
|
+
if (shape.agentKinds.some(isTesterKind)) {
|
|
84
|
+
await this.assertTesterInfraConfigured(workspaceId, block, initiatedBy);
|
|
85
|
+
}
|
|
86
|
+
// A `docker-compose`/`kubernetes`/`custom` service whose enabled chain reaches an env-consumer
|
|
87
|
+
// (tester / human-test / playwright) with NO enabled `deployer` before it would dead-end inside
|
|
88
|
+
// the consumer — nothing provisions the environment it reads. Fail fast with an actionable error.
|
|
89
|
+
await this.assertDeployerBeforeConsumer(workspaceId, block, shape.agentKinds, shape.enabled);
|
|
90
|
+
// A chain that INCLUDES an enabled Deployer needs the service's provisioning config (the
|
|
91
|
+
// "what/where") AND the workspace's infra handler (the "how") complete + correct — and, best
|
|
92
|
+
// effort, the deployment integration's live connection working — so a misconfigured environment
|
|
93
|
+
// fails loudly here with a fix-it pointer instead of an async failed env (or a silent no-op).
|
|
94
|
+
await this.assertDeployerConfigured(workspaceId, block, shape.agentKinds, shape.enabled, initiatedBy);
|
|
95
|
+
// A chain carrying an agent that relies on binary-artifact storage (the UI Tester uploads
|
|
96
|
+
// screenshots) needs the account to have storage configured.
|
|
97
|
+
await this.assertBinaryStorageConfigured(workspaceId, shape.agentKinds);
|
|
98
|
+
// A workspace that delegates container agents to a runner pool needs that pool registered
|
|
99
|
+
// (local mode opt-in). No-op on Cloudflare/Node (fixed backend) and when delegation is off.
|
|
100
|
+
await this.assertAgentBackendConfigured?.(workspaceId);
|
|
101
|
+
// Every step's canonical model must have a usable provider — a container step needs any
|
|
102
|
+
// usable flavour, an INLINE step needs an inline-usable one (a subscription-only model can't
|
|
103
|
+
// run inline without an inline harness). This is the gate a retry used to skip.
|
|
104
|
+
await this.assertProvidersConfiguredForPipeline(workspaceId, block, shape.agentKinds, initiatedBy);
|
|
105
|
+
// Refuse a metered run once the spend budget is reached (a clear error rather than a silent
|
|
106
|
+
// mid-run pause). A local/subscription-only pipeline is exempt.
|
|
107
|
+
await this.assertBudgetAllowsPipeline(workspaceId, block, shape.agentKinds, initiatedBy);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* The {@link PipelineShape} a retry/restart re-drives: the stored run's steps ARE the enabled,
|
|
111
|
+
* ordered chain that will run again, so {@link assertRunnable} validates exactly what
|
|
112
|
+
* re-executes rather than the current pipeline definition (which may have been edited out of
|
|
113
|
+
* band since the run started). Disabled steps were already filtered out at start, so every
|
|
114
|
+
* stored step is enabled.
|
|
115
|
+
*/
|
|
116
|
+
runnableShapeOf(steps) {
|
|
117
|
+
return {
|
|
118
|
+
agentKinds: steps.map((s) => s.agentKind),
|
|
119
|
+
gating: steps.map((s) => s.gating ?? null),
|
|
120
|
+
// The QC companion's live step-state carries the same `gating` config the pipeline set, so
|
|
121
|
+
// the tester-QC gating validation re-runs on a retry against exactly what re-executes.
|
|
122
|
+
testerQuality: steps.map((s) => s.testerQuality ?? null),
|
|
123
|
+
// The per-step options bag (carrying a `skill` step's `skillId`) is copied onto the run
|
|
124
|
+
// step at start, so the skill-step validation re-runs on retry against what re-executes.
|
|
125
|
+
stepOptions: steps.map((s) => s.stepOptions ?? null),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Refuse a task start while any of its dependencies is unfinished. A task may only run
|
|
130
|
+
* once every block it `dependsOn` has reached `done` (its PR merged). No-ops for
|
|
131
|
+
* non-task blocks and for tasks with no dependencies. Throws a {@link ConflictError}
|
|
132
|
+
* (→ 409, shown as a toast) naming the unfinished blockers so the human knows why.
|
|
133
|
+
*/
|
|
134
|
+
async assertDependenciesMet(workspaceId, block) {
|
|
135
|
+
if (block.level !== 'task' || block.dependsOn.length === 0)
|
|
136
|
+
return;
|
|
137
|
+
const blocks = await this.augmentWithCrossWorkspaceDeps(await this.blockRepository.listByWorkspace(workspaceId), block.dependsOn);
|
|
138
|
+
if (dependenciesMet(blocks, block.id))
|
|
139
|
+
return;
|
|
140
|
+
const blockers = unmetDependencies(blocks, block.id);
|
|
141
|
+
const names = blockers.map((b) => `"${b.title}"`).join(', ');
|
|
142
|
+
throw new ConflictError(`This task is blocked by ${blockers.length} unfinished dependenc${blockers.length === 1 ? 'y' : 'ies'}${names ? ` (${names})` : ''}. Finish them before starting this task.`, 'dependencies_unmet', { count: blockers.length, blockers: blockers.map((b) => b.title) });
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Augment a workspace's block list (in place) with any dependency blocks referenced by
|
|
146
|
+
* `depIds` that aren't already present — a `dependsOn` edge can point at a task homed in a
|
|
147
|
+
* DIFFERENT workspace (a shared/mounted service). Resolved via the cross-workspace
|
|
148
|
+
* {@link BlockRepository.findByIds} (one batched query, not a point-read per id), so a
|
|
149
|
+
* shared-service blocker is evaluated by its real status instead of being silently treated
|
|
150
|
+
* as satisfied (missing ⇒ done). Returns the same (now-augmented) array for chaining.
|
|
151
|
+
*/
|
|
152
|
+
async augmentWithCrossWorkspaceDeps(blocks, depIds) {
|
|
153
|
+
const have = new Set(blocks.map((b) => b.id));
|
|
154
|
+
const missing = [...new Set(depIds)].filter((id) => !have.has(id));
|
|
155
|
+
if (missing.length === 0)
|
|
156
|
+
return blocks;
|
|
157
|
+
for (const found of await this.blockRepository.findByIds(missing)) {
|
|
158
|
+
blocks.push(found.block);
|
|
159
|
+
}
|
|
160
|
+
return blocks;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Enforce the workspace's per-service running-task limit before a task run starts.
|
|
164
|
+
* No-ops unless the settings module is wired, the block is a task, and a limit mode
|
|
165
|
+
* is active. Counts the tasks under the same service frame that already have a live
|
|
166
|
+
* run (running / blocked / paused) — bucketed by task type when the mode is
|
|
167
|
+
* `per_type`, else shared across all types — and throws a {@link ConflictError} (→ 409,
|
|
168
|
+
* shown as a toast) when the cap is reached. The starting block is excluded from the
|
|
169
|
+
* count (its prior run is about to be replaced).
|
|
170
|
+
*/
|
|
171
|
+
async assertWithinTaskLimit(workspaceId, block) {
|
|
172
|
+
const settingsService = this.workspaceSettingsService;
|
|
173
|
+
if (!settingsService || block.level !== 'task')
|
|
174
|
+
return;
|
|
175
|
+
const settings = await settingsService.get(workspaceId);
|
|
176
|
+
if (settings.taskLimitMode === 'off')
|
|
177
|
+
return;
|
|
178
|
+
const all = await this.blockRepository.listByWorkspace(workspaceId);
|
|
179
|
+
const byId = new Map(all.map((b) => [b.id, b]));
|
|
180
|
+
// Walk up to the owning service frame.
|
|
181
|
+
let frame = block;
|
|
182
|
+
let guard = 0;
|
|
183
|
+
while (frame && frame.level !== 'frame' && guard++ < 1000) {
|
|
184
|
+
frame = frame.parentId ? byId.get(frame.parentId) : undefined;
|
|
185
|
+
}
|
|
186
|
+
if (!frame || frame.level !== 'frame')
|
|
187
|
+
return; // orphan task — nothing to scope a service limit to
|
|
188
|
+
const frameId = frame.id;
|
|
189
|
+
const underFrame = (b) => {
|
|
190
|
+
let cur = b;
|
|
191
|
+
let hops = 0;
|
|
192
|
+
while (cur && hops++ < 1000) {
|
|
193
|
+
if (cur.id === frameId)
|
|
194
|
+
return true;
|
|
195
|
+
cur = cur.parentId ? byId.get(cur.parentId) : undefined;
|
|
196
|
+
}
|
|
197
|
+
return false;
|
|
198
|
+
};
|
|
199
|
+
// Lean projection of the workspace's live runs (block + status only) — avoids loading and
|
|
200
|
+
// JSON-decoding every historical run's `detail` just to read the handful of live block ids.
|
|
201
|
+
const live = await this.executionRepository.listLive(workspaceId);
|
|
202
|
+
const liveBlockIds = new Set(live.map((e) => e.blockId));
|
|
203
|
+
const siblingTasks = all.filter((b) => b.level === 'task' && b.id !== block.id && underFrame(b));
|
|
204
|
+
if (settings.taskLimitMode === 'shared') {
|
|
205
|
+
const limit = settings.taskLimitShared ?? 0;
|
|
206
|
+
const running = siblingTasks.filter((b) => liveBlockIds.has(b.id)).length;
|
|
207
|
+
if (running >= limit) {
|
|
208
|
+
throw new ConflictError(`"${frame.title}" is already running ${running} of ${limit} allowed task(s). ` +
|
|
209
|
+
`Wait for one to finish before starting another.`, 'task_limit_reached', { frame: frame.title, limit, running });
|
|
210
|
+
}
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
// per_type: only the configured types are capped; an unconfigured type is unbounded.
|
|
214
|
+
const type = block.taskType ?? 'feature';
|
|
215
|
+
const perType = (settings.taskLimitPerType ?? {});
|
|
216
|
+
const limit = perType[type];
|
|
217
|
+
if (limit == null)
|
|
218
|
+
return;
|
|
219
|
+
const running = siblingTasks.filter((b) => liveBlockIds.has(b.id) && (b.taskType ?? 'feature') === type).length;
|
|
220
|
+
if (running >= limit) {
|
|
221
|
+
throw new ConflictError(`"${frame.title}" is already running ${running} of ${limit} allowed ${type} task(s). ` +
|
|
222
|
+
`Wait for one to finish before starting another ${type} task.`, 'task_limit_reached', { frame: frame.title, limit, running, taskType: type });
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Whether a model id will incur metered monetary cost for THIS workspace. Non-metered:
|
|
227
|
+
* a subscription model whose vendor is connected ("subscriptions always win"), or a
|
|
228
|
+
* local-runner model (keyless, on the user's own endpoint). Everything else — including
|
|
229
|
+
* env-default routing (an absent id) and Cloudflare Workers AI — is treated as metered.
|
|
230
|
+
* Shared with {@link RunDispatcher.currentStepIsNonMetered} so the up-front budget gate
|
|
231
|
+
* and the mid-run spend gate can't classify a model differently.
|
|
232
|
+
*/
|
|
233
|
+
modelIdIsMetered(id, caps) {
|
|
234
|
+
const sub = subscriptionOptionFor(id);
|
|
235
|
+
if (sub && caps.subscriptionVendors.has(sub.vendor))
|
|
236
|
+
return false;
|
|
237
|
+
const ref = resolveModelRef(id, caps);
|
|
238
|
+
if (!ref)
|
|
239
|
+
return true;
|
|
240
|
+
if (ref.harness === 'claude-code' || ref.harness === 'codex')
|
|
241
|
+
return false;
|
|
242
|
+
return !isLocalRunner(ref.provider);
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Guard a run start when the pipeline carries a VISUAL step (`tester-ui` /
|
|
246
|
+
* `visual-confirmation`): such a step exercises a rendered UI, so it only makes sense where
|
|
247
|
+
* there is a UI to drive — a `type: 'frontend'` frame (it owns the app under test) or a frame
|
|
248
|
+
* a `frontend` frame links to (the linked frontend is the UI a change to that service is
|
|
249
|
+
* validated through). On any other frame (a service with no linked frontend, a `library` /
|
|
250
|
+
* `document` repo) a `tester-ui` step would have nothing to drive, so refuse the start with an
|
|
251
|
+
* actionable {@link ConflictError} (`visual_pipeline_no_frontend`). The frontend surfaces the
|
|
252
|
+
* SAME rule (via the shared `frameAllowsVisualPipeline`) so it only offers these pipelines
|
|
253
|
+
* where they can run; this is the server-side guarantee. A non-visual pipeline passes through.
|
|
254
|
+
* The workspace block list is read ONCE (for the frontend→service links), never per-frame.
|
|
255
|
+
*/
|
|
256
|
+
async assertPipelineFrameTypeAllowed(workspaceId, block, agentKinds) {
|
|
257
|
+
if (!pipelineHasVisualStep({ agentKinds: [...agentKinds] }))
|
|
258
|
+
return;
|
|
259
|
+
const frame = await this.contextBuilder.resolveServiceFrame(workspaceId, block.id);
|
|
260
|
+
// A `frontend` frame is always allowed without listing the workspace; only a non-frontend
|
|
261
|
+
// frame needs the link scan, so defer the (single) block-list read until then.
|
|
262
|
+
if (frame?.type === 'frontend')
|
|
263
|
+
return;
|
|
264
|
+
const blocks = await this.blockRepository.listByWorkspace(workspaceId);
|
|
265
|
+
if (frameAllowsVisualPipeline(frame, blocks))
|
|
266
|
+
return;
|
|
267
|
+
throw new ConflictError('This pipeline includes a UI-testing step, so it can only run on a frontend service (or a ' +
|
|
268
|
+
'backend service that has a frontend linked to it). Move the task under a frontend, link ' +
|
|
269
|
+
'a frontend to this service, or pick a pipeline without UI-testing steps.', 'visual_pipeline_no_frontend', { frameType: frame?.type ?? null });
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Guard a Tester pipeline's start on the service frame's declared provisioning being runnable.
|
|
273
|
+
* The Tester needs SOME way to stand its system up: `infraless` (or none declared) runs with no
|
|
274
|
+
* infra; `docker-compose`/`kubernetes`/`custom` are all provisioned by the single Deployer step
|
|
275
|
+
* through a workspace handler, so one must resolve for the service's type. A `frontend` frame is
|
|
276
|
+
* gated instead on having a live service under test. Throws an actionable {@link ConflictError}
|
|
277
|
+
* (`tester_infra_unsupported` for the frontend case, `provision_type_unhandled` for a missing
|
|
278
|
+
* handler); passes through when the provisioning seam is unwired (tests / no environment
|
|
279
|
+
* integration), like the other optional start guards. `initiatedBy` is threaded into
|
|
280
|
+
* `canProvision` so the run initiator's local per-user handler OVERRIDES resolve exactly as they
|
|
281
|
+
* do at provision time (and as the Deployer-config gate does) — else a valid override-only local
|
|
282
|
+
* setup would be falsely refused here while the deployer would actually provision it.
|
|
283
|
+
*/
|
|
284
|
+
async assertTesterInfraConfigured(workspaceId, block, initiatedBy) {
|
|
285
|
+
// A `frontend` frame (the self-contained UI-test flow) is gated on having a live service
|
|
286
|
+
// under test, NOT on a provision type — resolved first and short-circuiting the backend
|
|
287
|
+
// branch. Only enforce it when the environment seam is wired (else, like the other optional
|
|
288
|
+
// start guards, pass through so tests / no-env deployments run unchanged).
|
|
289
|
+
const frontend = await this.contextBuilder.resolveFrontendConfig(workspaceId, block);
|
|
290
|
+
if (frontend) {
|
|
291
|
+
if (!this.environmentProvisioning)
|
|
292
|
+
return;
|
|
293
|
+
const decision = decideTesterInfra({
|
|
294
|
+
frontend: {
|
|
295
|
+
hasServiceBindings: hasServiceBinding(frontend.config),
|
|
296
|
+
hasLiveService: hasLiveServiceBinding(frontend.bindings),
|
|
297
|
+
},
|
|
298
|
+
provisionType: undefined,
|
|
299
|
+
handlerResolves: true,
|
|
300
|
+
});
|
|
301
|
+
if (decision.ok)
|
|
302
|
+
return;
|
|
303
|
+
throw new ConflictError(TESTER_INFRA_MESSAGES[decision.reason], 'tester_infra_unsupported', {
|
|
304
|
+
infraReason: decision.reason,
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
const service = await this.contextBuilder.resolveServiceConfig(workspaceId, block);
|
|
308
|
+
// A `library` frame (not `liveTestable`) runs its unit/integration suite IN-CONTAINER — any
|
|
309
|
+
// repo-local docker-compose is test infra stood up on localhost, never a Deployer-provisioned
|
|
310
|
+
// env — so the tester never needs a workspace handler. Pass through regardless of provisioning.
|
|
311
|
+
if (service?.type && !frameProfile(service.type).liveTestable)
|
|
312
|
+
return;
|
|
313
|
+
const provisioning = service?.provisioning;
|
|
314
|
+
// `docker-compose`/`kubernetes`/`custom` are all provisioned by the Deployer via a workspace
|
|
315
|
+
// handler, so resolve it lazily — and only when the provisioning seam is wired (else pass
|
|
316
|
+
// through, treating it as resolvable). `infraless`/none needs no handler.
|
|
317
|
+
const needsHandler = provisioning?.type === 'docker-compose' ||
|
|
318
|
+
provisioning?.type === 'kubernetes' ||
|
|
319
|
+
provisioning?.type === 'custom';
|
|
320
|
+
const handlerResolves = needsHandler && this.environmentProvisioning
|
|
321
|
+
? (await this.environmentProvisioning.canProvision(workspaceId, provisioning, initiatedBy))
|
|
322
|
+
.ok
|
|
323
|
+
: true;
|
|
324
|
+
const decision = decideTesterInfra({ provisionType: provisioning?.type, handlerResolves });
|
|
325
|
+
if (decision.ok)
|
|
326
|
+
return;
|
|
327
|
+
// The only backend-branch refusal is a provision type with no resolvable handler.
|
|
328
|
+
throw new ConflictError(TESTER_INFRA_MESSAGES[decision.reason], 'provision_type_unhandled', {
|
|
329
|
+
provisionType: provisioning.type,
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Fail fast when a `docker-compose`/`kubernetes`/`custom` service's chain would dead-end at an
|
|
334
|
+
* env-consumer (tester / human-test / playwright) because no enabled `deployer` provisions the
|
|
335
|
+
* environment before it — the exact silent dead-end this initiative fixes (the tester picks
|
|
336
|
+
* ephemeral mode from the provision type but finds no coordinates). The pure ordering check lives
|
|
337
|
+
* in {@link needsDeployerBeforeConsumer}; here we resolve the service's provision type (only when a
|
|
338
|
+
* consumer is present, so consumer-less chains skip the read) and translate a positive verdict
|
|
339
|
+
* into an actionable {@link ConflictError}. Pass-through for infraless/frontend services and for
|
|
340
|
+
* chains with a deployer before the first consumer.
|
|
341
|
+
*/
|
|
342
|
+
async assertDeployerBeforeConsumer(workspaceId, block, agentKinds, enabled) {
|
|
343
|
+
const hasConsumer = agentKinds.some((kind, i) => enabled?.[i] !== false && ENV_CONSUMER_KINDS.includes(kind));
|
|
344
|
+
if (!hasConsumer)
|
|
345
|
+
return;
|
|
346
|
+
const service = await this.contextBuilder.resolveServiceConfig(workspaceId, block);
|
|
347
|
+
// A `library` frame stands nothing up via the Deployer (its tester runs the suite in-container),
|
|
348
|
+
// so a missing Deployer before the tester is never a dead-end — pass through like `infraless`.
|
|
349
|
+
if (service?.type && !frameProfile(service.type).deployable)
|
|
350
|
+
return;
|
|
351
|
+
if (!needsDeployerBeforeConsumer(agentKinds, enabled, service?.provisioning?.type))
|
|
352
|
+
return;
|
|
353
|
+
throw new ConflictError(`This service provisions a '${service.provisioning.type}' environment, but this pipeline ` +
|
|
354
|
+
'has no Deployer step before its first Tester / human-test step, so the environment would ' +
|
|
355
|
+
'never be stood up. Reseed this pipeline to the latest built-in (which includes a Deployer) ' +
|
|
356
|
+
'and start a new run, or set the service to docker-compose / infraless.', 'deployer_required_before_tester', { provisionType: service.provisioning.type });
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Guard a pipeline that INCLUDES an enabled `deployer` step on its ephemeral-environment config
|
|
360
|
+
* being FULL + CORRECT on BOTH sides of the "what/where ÷ how" split, so a misconfigured
|
|
361
|
+
* environment fails LOUDLY at start with a fixable pointer instead of mid-run: a `kubernetes` /
|
|
362
|
+
* `custom` service silently failing its async provision, or a `docker-compose` one whose deployer
|
|
363
|
+
* NO-OPS because no handler resolves (the exact silent dead-ends this initiative closes). It
|
|
364
|
+
* checks, in order of the fix a human would make:
|
|
365
|
+
* 1. the SERVICE's provisioning config is complete for its declared type (manifest source /
|
|
366
|
+
* compose path / custom-manifest id) — else `deployer_service_provisioning_incomplete`;
|
|
367
|
+
* 2. a WORKSPACE handler resolves for the type — else `provision_type_unhandled` (the same
|
|
368
|
+
* reason the Tester gate raises; a MISSING/ambiguous handler, not a broken one);
|
|
369
|
+
* 3. (bonus, best-effort) the resolved deployment integration's live connection PROBES green —
|
|
370
|
+
* else `deployer_connection_test_failed`, carrying the provider's failure detail.
|
|
371
|
+
* Each `ConflictError` carries a machine-readable reason + details the SPA deep-links off to the
|
|
372
|
+
* exact fix surface. Pass-through for `infraless`/undeclared services (the deployer stands nothing
|
|
373
|
+
* up) and when the environment seam is unwired (tests / no-env deployments), like the other
|
|
374
|
+
* optional start guards.
|
|
375
|
+
*/
|
|
376
|
+
async assertDeployerConfigured(workspaceId, block, agentKinds, enabled, initiatedBy) {
|
|
377
|
+
if (!this.environmentProvisioning)
|
|
378
|
+
return;
|
|
379
|
+
if (!hasEnabledDeployerStep(agentKinds, enabled))
|
|
380
|
+
return;
|
|
381
|
+
const service = await this.contextBuilder.resolveServiceConfig(workspaceId, block);
|
|
382
|
+
// A Deployer on a `library` frame (not `deployable`) is a safe no-op regardless of any declared
|
|
383
|
+
// provisioning — the runtime deploy loop records a library skip — so there is nothing to
|
|
384
|
+
// validate. Checked BEFORE the provisioning branch, since a library may declare a compose path
|
|
385
|
+
// as repo-local TEST infra (not a deployable env).
|
|
386
|
+
if (service?.type && !frameProfile(service.type).deployable)
|
|
387
|
+
return;
|
|
388
|
+
const provisioning = service?.provisioning;
|
|
389
|
+
// A Deployer on an `infraless`/undeclared service is a safe no-op (nothing to provision), so
|
|
390
|
+
// there is nothing to validate — matching the deployer's own skip in advanceDeployerFrames.
|
|
391
|
+
if (!provisioning || provisioning.type === 'infraless')
|
|
392
|
+
return;
|
|
393
|
+
const type = provisioning.type;
|
|
394
|
+
const serviceIssues = deployerServiceConfigIssues(provisioning);
|
|
395
|
+
// `canProvision` is a single batched handler read (no decrypt / no N+1); safe to run eagerly.
|
|
396
|
+
// Pass the initiator so a local per-user handler override resolves exactly as provisioning does
|
|
397
|
+
// (else a valid override-only local setup would be falsely reported as unhandled).
|
|
398
|
+
const handlerResolution = await this.environmentProvisioning.canProvision(workspaceId, provisioning, initiatedBy);
|
|
399
|
+
// Only probe the LIVE connection when the structural config is sound — a network probe is
|
|
400
|
+
// wasted (and its verdict misleading) while the service config is incomplete or no handler
|
|
401
|
+
// resolves. A probe FAULT (transient network / provider-build hiccup) is not a definitive
|
|
402
|
+
// "connection broken" verdict, so swallow it and let the async provision surface a real fault
|
|
403
|
+
// rather than blocking the start on a flake.
|
|
404
|
+
let connectionTest;
|
|
405
|
+
if (serviceIssues.length === 0 && handlerResolution.ok) {
|
|
406
|
+
try {
|
|
407
|
+
connectionTest =
|
|
408
|
+
(await this.environmentProvisioning.testProvisioning(workspaceId, provisioning, initiatedBy)) ?? undefined;
|
|
409
|
+
}
|
|
410
|
+
catch {
|
|
411
|
+
connectionTest = undefined;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
const decision = decideDeployerConfig({
|
|
415
|
+
provisionType: type,
|
|
416
|
+
serviceIssues,
|
|
417
|
+
handlerResolution,
|
|
418
|
+
...(connectionTest ? { connectionTest } : {}),
|
|
419
|
+
});
|
|
420
|
+
if (decision.ok)
|
|
421
|
+
return;
|
|
422
|
+
if (decision.reason === 'service-config-incomplete') {
|
|
423
|
+
// Deep-link target: the service FRAME's environment config (the inspector / compose wizard).
|
|
424
|
+
const frameId = block.level === 'frame'
|
|
425
|
+
? block.id
|
|
426
|
+
: ((await this.contextBuilder.resolveServiceFrameId(workspaceId, block.id)) ?? undefined);
|
|
427
|
+
throw new ConflictError(`This service provisions a '${type}' environment via the Deployer, but its environment ` +
|
|
428
|
+
`configuration is incomplete (missing: ${decision.missing.join(', ')}). Complete the ` +
|
|
429
|
+
"service's environment configuration before starting.", 'deployer_service_provisioning_incomplete', { provisionType: type, missing: [...decision.missing], ...(frameId ? { frameId } : {}) });
|
|
430
|
+
}
|
|
431
|
+
if (decision.reason === 'workspace-unhandled') {
|
|
432
|
+
throw new ConflictError(`This service provisions a '${type}' environment via the Deployer, but this workspace has ` +
|
|
433
|
+
(decision.handlerReason === 'type-mismatch'
|
|
434
|
+
? `more than one handler matching it — pin a manifest id to disambiguate, `
|
|
435
|
+
: `no infrastructure handler configured for that type — `) +
|
|
436
|
+
'configure a handler (Infrastructure → Test environments), or set the service to ' +
|
|
437
|
+
'infraless, before starting.', 'provision_type_unhandled', { provisionType: type });
|
|
438
|
+
}
|
|
439
|
+
// decision.reason === 'connection-failed'
|
|
440
|
+
throw new ConflictError(`The '${type}' deployment integration for this service isn't working: ` +
|
|
441
|
+
`${decision.message ?? 'the connection test failed'}. Check the handler's endpoint and ` +
|
|
442
|
+
'credentials (Infrastructure → Test environments) and re-test the connection, then start ' +
|
|
443
|
+
'again.', 'deployer_connection_test_failed', { provisionType: type, ...(decision.message ? { detail: decision.message } : {}) });
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Guard a pipeline's start when it carries an agent kind that RELIES on binary-artifact
|
|
447
|
+
* storage (the {@link BINARY_STORAGE_TRAIT}, e.g. the UI Tester, which uploads its
|
|
448
|
+
* screenshots there). Such a run would otherwise dispatch and then fail/degrade with no
|
|
449
|
+
* place to store its artifacts, so refuse it up-front with a clear, actionable
|
|
450
|
+
* `binary_storage_unconfigured` conflict the SPA turns into a "configure storage" prompt.
|
|
451
|
+
* The check is trait-driven so it stays universal: a future artifact-producing kind just
|
|
452
|
+
* carries the trait. Pass-through when no store resolver is wired (tests/conformance with
|
|
453
|
+
* no storage) — matching the other optional start guards.
|
|
454
|
+
*/
|
|
455
|
+
async assertBinaryStorageConfigured(workspaceId, agentKinds) {
|
|
456
|
+
if (!agentKinds.some((kind) => hasTrait(kind, BINARY_STORAGE_TRAIT, this.agentKindRegistry)))
|
|
457
|
+
return;
|
|
458
|
+
const resolve = this.resolveBinaryArtifactStore;
|
|
459
|
+
if (!resolve)
|
|
460
|
+
return;
|
|
461
|
+
const store = await resolve(workspaceId);
|
|
462
|
+
if (store)
|
|
463
|
+
return;
|
|
464
|
+
throw new ConflictError('This pipeline includes an agent that needs binary storage (e.g. the UI Tester, which uploads its screenshots), but this account has no content storage configured. Configure content storage to run it.', 'binary_storage_unconfigured');
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Guard a pipeline's start on having a usable provider for every step's canonical
|
|
468
|
+
* model. The model a step runs is resolved by the same precedence the dispatch path
|
|
469
|
+
* uses (block pin → workspace per-kind default); each canonical id must have a usable
|
|
470
|
+
* provider given what's configured — a direct API key for its provider, a connected
|
|
471
|
+
* subscription vendor, or the opt-in Cloudflare lib enabled. Env-routing defaults (the
|
|
472
|
+
* last fallback, with no catalog id) are operator-level and not gated, matching the
|
|
473
|
+
* personal-credential gate. A throw aborts the start cleanly before any side effects.
|
|
474
|
+
* Skipped when no capability resolver is wired (tests / unconfigured facades).
|
|
475
|
+
*/
|
|
476
|
+
async assertProvidersConfiguredForPipeline(workspaceId, block, agentKinds, initiatedBy) {
|
|
477
|
+
if (!this.resolveProviderCapabilities)
|
|
478
|
+
return;
|
|
479
|
+
const caps = await this.resolveProviderCapabilities(workspaceId, initiatedBy);
|
|
480
|
+
const runsInline = this.inlineHarnessRef;
|
|
481
|
+
// Two failure buckets, so the error can steer the fix precisely:
|
|
482
|
+
// - `unconfigured`: no usable provider AT ALL (container or inline) — add a key/sub/CF.
|
|
483
|
+
// - `inlineUnsatisfiable`: usable for a container step but NOT for an INLINE step — a
|
|
484
|
+
// subscription-only model an inline `generateText` call can't drive (and this
|
|
485
|
+
// deployment can't run the harness inline). The remedy is different (pin an
|
|
486
|
+
// inline-capable model, or a preset whose inline steps resolve to one), so a subscription
|
|
487
|
+
// model that satisfies the container steps but strands the reviewer/brainstorm/estimator
|
|
488
|
+
// is refused up front instead of failing mid-run against an ungated env default.
|
|
489
|
+
// - `policyBlocked`: the account-wide model-family policy blocks the model on its
|
|
490
|
+
// effective route — a distinct, more actionable reason than "unconfigured", so it is
|
|
491
|
+
// checked FIRST and short-circuits the other buckets for that id.
|
|
492
|
+
const unconfigured = new Set();
|
|
493
|
+
const inlineUnsatisfiable = new Set();
|
|
494
|
+
const policyBlocked = new Set();
|
|
495
|
+
const check = (id, inline) => {
|
|
496
|
+
if (!id)
|
|
497
|
+
return;
|
|
498
|
+
if (caps.modelPolicy &&
|
|
499
|
+
!isAllowedByFamilyPolicy(id, resolveModelRef(id, caps)?.provider, caps.modelPolicy)) {
|
|
500
|
+
policyBlocked.add(id);
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
if (!isModelUsable(id, caps))
|
|
504
|
+
unconfigured.add(id);
|
|
505
|
+
else if (inline && !isModelUsableInline(id, caps, runsInline))
|
|
506
|
+
inlineUnsatisfiable.add(id);
|
|
507
|
+
};
|
|
508
|
+
if (block.modelId) {
|
|
509
|
+
// A block-level pin applies to every step; it must satisfy an inline step too when the
|
|
510
|
+
// pipeline has one.
|
|
511
|
+
check(block.modelId, agentKinds.some((kind) => isInlineModelStep(kind, this.agentKindRegistry)));
|
|
512
|
+
}
|
|
513
|
+
else if (this.resolveWorkspaceModelDefault) {
|
|
514
|
+
// Independent per-kind resolutions on the start path — run them concurrently.
|
|
515
|
+
const ids = await Promise.all(agentKinds.map((kind) => this.resolveWorkspaceModelDefault(workspaceId, kind, block.modelPresetId)));
|
|
516
|
+
agentKinds.forEach((kind, i) => check(ids[i], isInlineModelStep(kind, this.agentKindRegistry)));
|
|
517
|
+
}
|
|
518
|
+
if (policyBlocked.size > 0) {
|
|
519
|
+
throw new ConflictError(`This pipeline uses models blocked by the account's model-family policy: ` +
|
|
520
|
+
`${[...policyBlocked].join(', ')}. Pick a model from an allowed family (or a ` +
|
|
521
|
+
'residency-guaranteed route), or ask an account admin to adjust the policy.', 'model_policy_blocked', { models: [...policyBlocked] });
|
|
522
|
+
}
|
|
523
|
+
if (unconfigured.size > 0) {
|
|
524
|
+
throw new ConflictError(`This pipeline uses models with no configured provider: ${[...unconfigured].join(', ')}. ` +
|
|
525
|
+
'Add an API key for the provider, connect a subscription, or enable Cloudflare AI ' +
|
|
526
|
+
'before starting.', 'providers_unconfigured', { models: [...unconfigured] });
|
|
527
|
+
}
|
|
528
|
+
if (inlineUnsatisfiable.size > 0) {
|
|
529
|
+
throw new ConflictError(`This pipeline has inline steps (e.g. the requirements reviewer) whose model ` +
|
|
530
|
+
`cannot run inline: ${[...inlineUnsatisfiable].join(', ')}. A subscription-only model ` +
|
|
531
|
+
'(Claude / GPT / GLM) runs only in the container agents, not the inline reviewers — ' +
|
|
532
|
+
'and this deployment has no inline harness. Pick a model preset whose inline steps ' +
|
|
533
|
+
'resolve to a provider-backed model (a direct API key, OpenRouter, or Cloudflare AI), ' +
|
|
534
|
+
'or run local mode with the ambient Claude Code / Codex CLI enabled.', 'preset_unsatisfiable', { models: [...inlineUnsatisfiable] });
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Refuse to START / RETRY a run when the workspace has reached its spend budget AND the
|
|
539
|
+
* pipeline has at least one budget-METERED step. A `0` (or exhausted) budget is a
|
|
540
|
+
* deliberate "no paid spend" setting, but it must surface as a clear, up-front error here
|
|
541
|
+
* rather than a silent mid-run pause. Steps that incur no metered cost — a connected
|
|
542
|
+
* subscription model, or a keyless local-runner model — are exempt, so a workspace that
|
|
543
|
+
* runs ONLY local/subscription models starts normally even at a `0` budget. Best-effort:
|
|
544
|
+
* with no capability resolver wired (tests/unconfigured) it is skipped and the mid-run
|
|
545
|
+
* gate still guards. Before any side effects, matching the other start guards.
|
|
546
|
+
*/
|
|
547
|
+
async assertBudgetAllowsPipeline(workspaceId, block, agentKinds, initiatedBy) {
|
|
548
|
+
const accountId = await this.workspaceRepository.accountOf(workspaceId);
|
|
549
|
+
if (!(await this.spend.isOverBudget(workspaceId, { accountId, userId: initiatedBy })))
|
|
550
|
+
return;
|
|
551
|
+
if (!this.resolveProviderCapabilities)
|
|
552
|
+
return;
|
|
553
|
+
const caps = await this.resolveProviderCapabilities(workspaceId, initiatedBy);
|
|
554
|
+
const ids = [];
|
|
555
|
+
if (block.modelId) {
|
|
556
|
+
ids.push(block.modelId);
|
|
557
|
+
}
|
|
558
|
+
else if (this.resolveWorkspaceModelDefault) {
|
|
559
|
+
ids.push(...(await Promise.all(agentKinds.map((kind) => this.resolveWorkspaceModelDefault(workspaceId, kind, block.modelPresetId)))));
|
|
560
|
+
}
|
|
561
|
+
else {
|
|
562
|
+
ids.push(undefined);
|
|
563
|
+
}
|
|
564
|
+
if (!ids.some((id) => this.modelIdIsMetered(id, caps)))
|
|
565
|
+
return;
|
|
566
|
+
throw new ConflictError('This run has reached a spend budget (workspace, account, or user). New runs on metered ' +
|
|
567
|
+
'models are paused until the budget is raised or the billing period resets. A task pinned ' +
|
|
568
|
+
'to a local model or a connected subscription still runs.');
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
//# sourceMappingURL=RunAdmission.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RunAdmission.js","sourceRoot":"","sources":["../../../src/modules/execution/RunAdmission.ts"],"names":[],"mappings":"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"}
|