@cat-factory/orchestration 0.313.2 → 0.314.1
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/container/dependencies.d.ts +10 -1
- package/dist/container/dependencies.d.ts.map +1 -1
- package/dist/container/execution-service.d.ts.map +1 -1
- package/dist/container/execution-service.js +1 -0
- package/dist/container/execution-service.js.map +1 -1
- package/dist/container/runtime.d.ts +1 -0
- package/dist/container/runtime.d.ts.map +1 -1
- package/dist/container/runtime.js +5 -1
- package/dist/container/runtime.js.map +1 -1
- package/dist/container.d.ts +8 -1
- package/dist/container.d.ts.map +1 -1
- package/dist/container.js +2 -1
- package/dist/container.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/modules/debug/RunDebugService.d.ts.map +1 -1
- package/dist/modules/debug/RunDebugService.js +20 -2
- package/dist/modules/debug/RunDebugService.js.map +1 -1
- package/dist/modules/debug/llmReporting.logic.d.ts +24 -0
- package/dist/modules/debug/llmReporting.logic.d.ts.map +1 -0
- package/dist/modules/debug/llmReporting.logic.js +35 -0
- package/dist/modules/debug/llmReporting.logic.js.map +1 -0
- package/dist/modules/execution/AgentDispatchController.d.ts +7 -0
- package/dist/modules/execution/AgentDispatchController.d.ts.map +1 -1
- package/dist/modules/execution/AgentDispatchController.js +40 -24
- package/dist/modules/execution/AgentDispatchController.js.map +1 -1
- package/dist/modules/execution/DeployFixController.d.ts +9 -0
- package/dist/modules/execution/DeployFixController.d.ts.map +1 -1
- package/dist/modules/execution/DeployFixController.js +10 -10
- package/dist/modules/execution/DeployFixController.js.map +1 -1
- package/dist/modules/execution/DeployerStepController.d.ts.map +1 -1
- package/dist/modules/execution/DeployerStepController.js +4 -3
- package/dist/modules/execution/DeployerStepController.js.map +1 -1
- package/dist/modules/execution/ExecutionService.d.ts +7 -0
- package/dist/modules/execution/ExecutionService.d.ts.map +1 -1
- package/dist/modules/execution/ExecutionService.js +17 -0
- package/dist/modules/execution/ExecutionService.js.map +1 -1
- package/dist/modules/execution/ExecutionServiceDependencies.d.ts +8 -1
- package/dist/modules/execution/ExecutionServiceDependencies.d.ts.map +1 -1
- package/dist/modules/execution/GateHelperDispatcher.d.ts +8 -0
- package/dist/modules/execution/GateHelperDispatcher.d.ts.map +1 -1
- package/dist/modules/execution/GateHelperDispatcher.js +9 -5
- package/dist/modules/execution/GateHelperDispatcher.js.map +1 -1
- package/dist/modules/execution/GateStepController.d.ts.map +1 -1
- package/dist/modules/execution/GateStepController.js +9 -3
- package/dist/modules/execution/GateStepController.js.map +1 -1
- package/dist/modules/execution/HumanTestController.d.ts +7 -0
- package/dist/modules/execution/HumanTestController.d.ts.map +1 -1
- package/dist/modules/execution/HumanTestController.js +20 -8
- package/dist/modules/execution/HumanTestController.js.map +1 -1
- package/dist/modules/execution/OneShotStepController.d.ts +1 -1
- package/dist/modules/execution/OneShotStepController.js +1 -1
- package/dist/modules/execution/PollCompletionController.d.ts +22 -3
- package/dist/modules/execution/PollCompletionController.d.ts.map +1 -1
- package/dist/modules/execution/PollCompletionController.js +78 -8
- package/dist/modules/execution/PollCompletionController.js.map +1 -1
- package/dist/modules/execution/PollRunningController.d.ts +22 -7
- package/dist/modules/execution/PollRunningController.d.ts.map +1 -1
- package/dist/modules/execution/PollRunningController.js +64 -13
- package/dist/modules/execution/PollRunningController.js.map +1 -1
- package/dist/modules/execution/RalphController.d.ts +7 -0
- package/dist/modules/execution/RalphController.d.ts.map +1 -1
- package/dist/modules/execution/RalphController.js +12 -8
- package/dist/modules/execution/RalphController.js.map +1 -1
- package/dist/modules/execution/RunDispatcher.d.ts.map +1 -1
- package/dist/modules/execution/RunDispatcher.js +19 -6
- package/dist/modules/execution/RunDispatcher.js.map +1 -1
- package/dist/modules/execution/RunDispatcherDependencies.d.ts +16 -1
- package/dist/modules/execution/RunDispatcherDependencies.d.ts.map +1 -1
- package/dist/modules/execution/RunDispatcherDependencies.js.map +1 -1
- package/dist/modules/execution/RunStateMachine.d.ts.map +1 -1
- package/dist/modules/execution/RunStateMachine.js +21 -2
- package/dist/modules/execution/RunStateMachine.js.map +1 -1
- package/dist/modules/execution/StepGraph.d.ts.map +1 -1
- package/dist/modules/execution/StepGraph.js +7 -0
- package/dist/modules/execution/StepGraph.js.map +1 -1
- package/dist/modules/execution/TesterController.d.ts +7 -0
- package/dist/modules/execution/TesterController.d.ts.map +1 -1
- package/dist/modules/execution/TesterController.js +24 -18
- package/dist/modules/execution/TesterController.js.map +1 -1
- package/dist/modules/execution/VisualConfirmationController.d.ts +7 -0
- package/dist/modules/execution/VisualConfirmationController.d.ts.map +1 -1
- package/dist/modules/execution/VisualConfirmationController.js +20 -8
- package/dist/modules/execution/VisualConfirmationController.js.map +1 -1
- package/dist/modules/execution/advance.d.ts +14 -0
- package/dist/modules/execution/advance.d.ts.map +1 -1
- package/dist/modules/execution/awaitingJob.logic.d.ts +30 -0
- package/dist/modules/execution/awaitingJob.logic.d.ts.map +1 -0
- package/dist/modules/execution/awaitingJob.logic.js +62 -0
- package/dist/modules/execution/awaitingJob.logic.js.map +1 -0
- package/dist/modules/execution/delegation.logic.d.ts +93 -0
- package/dist/modules/execution/delegation.logic.d.ts.map +1 -0
- package/dist/modules/execution/delegation.logic.js +97 -0
- package/dist/modules/execution/delegation.logic.js.map +1 -0
- package/dist/modules/execution/deployer-family.d.ts.map +1 -1
- package/dist/modules/execution/deployer-family.js +1 -0
- package/dist/modules/execution/deployer-family.js.map +1 -1
- package/dist/modules/execution/drive.d.ts.map +1 -1
- package/dist/modules/execution/drive.js +6 -1
- package/dist/modules/execution/drive.js.map +1 -1
- package/dist/modules/execution/gate-window-controllers.d.ts +7 -0
- package/dist/modules/execution/gate-window-controllers.d.ts.map +1 -1
- package/dist/modules/execution/gate-window-controllers.js +5 -1
- package/dist/modules/execution/gate-window-controllers.js.map +1 -1
- package/dist/modules/execution/job.logic.d.ts +38 -2
- package/dist/modules/execution/job.logic.d.ts.map +1 -1
- package/dist/modules/execution/job.logic.js +34 -0
- package/dist/modules/execution/job.logic.js.map +1 -1
- package/dist/modules/execution/step-fold.logic.d.ts +218 -2
- package/dist/modules/execution/step-fold.logic.d.ts.map +1 -1
- package/dist/modules/execution/step-fold.logic.js +413 -3
- package/dist/modules/execution/step-fold.logic.js.map +1 -1
- package/dist/validation/validateRegistrations.d.ts +11 -1
- package/dist/validation/validateRegistrations.d.ts.map +1 -1
- package/dist/validation/validateRegistrations.js +86 -1
- package/dist/validation/validateRegistrations.js.map +1 -1
- package/package.json +12 -12
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { sameSubtasks } from '@cat-factory/kernel';
|
|
1
|
+
import { sameSubtasks, } from '@cat-factory/kernel';
|
|
2
2
|
import { shouldPersistActivity } from './job.logic.js';
|
|
3
3
|
// The "fold one job update onto the step" family: the small, pure-ish mutators the poll paths
|
|
4
4
|
// (agent + deployer) apply to a running step, each returning whether anything actually changed so
|
|
@@ -28,15 +28,107 @@ import { shouldPersistActivity } from './job.logic.js';
|
|
|
28
28
|
* - `initiatedByUserId` — the quota-cycle counters' fallback target for a PERSONAL
|
|
29
29
|
* (individual-usage) run, which leases no pooled token; absent, the target is null.
|
|
30
30
|
*/
|
|
31
|
-
export function pollHandleFor(step, workspaceId, executionId
|
|
31
|
+
export function pollHandleFor(step, workspaceId, executionId,
|
|
32
|
+
/**
|
|
33
|
+
* The run's block. A PARAMETER rather than something read off the step, like `workspaceId` and
|
|
34
|
+
* `executionId` beside it, and load-bearing for the same reason they are: the delegated arm
|
|
35
|
+
* re-resolves its executor's credentials on every poll, and a lookup a per-service credential
|
|
36
|
+
* store cannot scope returns nothing, so the step polls for its whole life with an empty bag.
|
|
37
|
+
*/
|
|
38
|
+
blockId) {
|
|
32
39
|
return {
|
|
33
40
|
jobId: step.jobId,
|
|
34
41
|
runId: executionId,
|
|
35
42
|
workspaceId,
|
|
43
|
+
blockId,
|
|
36
44
|
agentKind: step.agentKind,
|
|
37
45
|
model: step.model,
|
|
38
46
|
subscriptionTokenId: step.subscriptionTokenId,
|
|
39
47
|
initiatedByUserId: step.initiatedByUserId,
|
|
48
|
+
...delegationHandleSlice(step),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The delegation record the step's IN-FLIGHT job belongs to, or undefined when the job in flight is
|
|
53
|
+
* not that record's.
|
|
54
|
+
*
|
|
55
|
+
* The ONE question every reader of `step.delegated` actually has, and asking `if (step.delegated)`
|
|
56
|
+
* instead is the shape that gets it wrong. A step whose own work was delegated can still dispatch a
|
|
57
|
+
* CONTAINER job afterwards (a helper round, a re-run under an overriding kind, a PR-review `fix`
|
|
58
|
+
* resolution), and the delegation record outlives that by design: its attempt log is the evidence
|
|
59
|
+
* for why the step is being re-run, and `resetStepForRerun` clears `jobId` and deliberately not the
|
|
60
|
+
* record. So a bare truthiness test routes that container job's poll to an external system, folds
|
|
61
|
+
* its phase onto external work that finished hours ago, and settles the external record on the
|
|
62
|
+
* container's outcome: three different systems' facts written onto one another.
|
|
63
|
+
*
|
|
64
|
+
* Keyed on the correlation key rather than on the record's status because the status is what the
|
|
65
|
+
* fold is about to CHANGE; the key is what says whose job this is, which is exactly why it is
|
|
66
|
+
* persisted (see `runDelegationSchema.correlationKey`).
|
|
67
|
+
*/
|
|
68
|
+
export function inFlightDelegation(step) {
|
|
69
|
+
const record = step.delegated;
|
|
70
|
+
if (!record || step.jobId !== record.correlationKey)
|
|
71
|
+
return undefined;
|
|
72
|
+
return record;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* The job id a re-entering advance may RE-ATTACH to, or undefined when there is nothing to
|
|
76
|
+
* re-attach to and the step must dispatch.
|
|
77
|
+
*
|
|
78
|
+
* Every dispatch site guards on "does this step already hold a job", and `step.jobId` alone is the
|
|
79
|
+
* wrong question for a delegated one. The claim is committed BEFORE `start()` is called, so a
|
|
80
|
+
* process that dies in between (a workerd isolate kill, a pg-boss worker restart, a deploy drain)
|
|
81
|
+
* leaves a job id addressing work that may never have been started. Read as a live handle, the
|
|
82
|
+
* replay skips its whole dispatch block and polls: the executor is asked to recover a run by
|
|
83
|
+
* correlation, answers "not yet" for ever because nothing was ever queued, and the step is failed
|
|
84
|
+
* as a TIMEOUT once the poll budget is spent, hours later and naming the wrong fault.
|
|
85
|
+
*
|
|
86
|
+
* A claim still `starting` is exactly that state and nothing else: {@link stampDelegationDispatch}
|
|
87
|
+
* moves it to `running` the moment the executor answers, and {@link failDelegationDispatch} drops
|
|
88
|
+
* the job id when it throws. So the honest answer is "no live job", and the site re-dispatches
|
|
89
|
+
* under the SAME correlation key (the dispatch epoch has not moved), which is precisely what the
|
|
90
|
+
* port's idempotency requirement is for: `start` recognises its own run, or starts the one that
|
|
91
|
+
* never began.
|
|
92
|
+
*/
|
|
93
|
+
export function liveJobId(step) {
|
|
94
|
+
if (!step.jobId)
|
|
95
|
+
return undefined;
|
|
96
|
+
if (inFlightDelegation(step)?.status === 'starting')
|
|
97
|
+
return undefined;
|
|
98
|
+
return step.jobId;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* The `delegated` slice of a rebuilt poll handle: which registered executor the step dispatched to
|
|
102
|
+
* and what it knows about the external work.
|
|
103
|
+
*
|
|
104
|
+
* A delegated step's poll has NOTHING else to route on. The engine's poll site holds a step and a
|
|
105
|
+
* run; the executor id lives only on this record, and without it `CompositeAgentExecutor.pollJob`
|
|
106
|
+
* cannot tell a delegated step from a container one and polls a container that was never started.
|
|
107
|
+
*
|
|
108
|
+
* Gated on {@link inFlightDelegation}, so the slice is attached only when the job being polled IS
|
|
109
|
+
* the delegated one. Without that gate a container job dispatched later on the same step is handed
|
|
110
|
+
* to the external executor, which polls its system for a run that does not exist while the real
|
|
111
|
+
* container job is never polled at all.
|
|
112
|
+
*
|
|
113
|
+
* The `externalId` FALLS BACK to the step's job id, which is the correlation key by construction
|
|
114
|
+
* (the gate above makes them the same string). A floor rather than a path anything depends on: an
|
|
115
|
+
* accepted dispatch always records an id (the port refuses a `start` that answers none), and a
|
|
116
|
+
* claim the dispatch never answered is re-dispatched rather than polled (see {@link liveJobId}).
|
|
117
|
+
* It survives because a handle with no id at all cannot be addressed, and the correlation key is
|
|
118
|
+
* the one string the executor was asked to make its run findable by.
|
|
119
|
+
*/
|
|
120
|
+
function delegationHandleSlice(step) {
|
|
121
|
+
const record = inFlightDelegation(step);
|
|
122
|
+
if (!record)
|
|
123
|
+
return {};
|
|
124
|
+
return {
|
|
125
|
+
delegated: {
|
|
126
|
+
executor: record.executor,
|
|
127
|
+
externalId: record.externalId ?? record.correlationKey,
|
|
128
|
+
...(record.url ? { url: record.url } : {}),
|
|
129
|
+
...(record.branches ? { branches: record.branches } : {}),
|
|
130
|
+
...(record.repo ? { repo: record.repo } : {}),
|
|
131
|
+
},
|
|
40
132
|
};
|
|
41
133
|
}
|
|
42
134
|
/**
|
|
@@ -80,6 +172,13 @@ export function recordDispatchAttribution(step, handle, dispatchedKind) {
|
|
|
80
172
|
// container path started) never erases the container round's record.
|
|
81
173
|
if (handle.toolServers)
|
|
82
174
|
stampToolServers(step, handle.toolServers, dispatchedKind);
|
|
175
|
+
// The DELEGATION the dispatch resolved: the external id the executor answered with, and the page
|
|
176
|
+
// a human watches it on. Folded here, with the rest of the attribution, because the poll site
|
|
177
|
+
// rebuilds its handle from the step alone and this is the only route from the accepted dispatch
|
|
178
|
+
// to it. Merged onto the CLAIM rather than replacing it, so the executor id and the attempt log
|
|
179
|
+
// the claim wrote survive; the status moves to `running` because the executor has answered.
|
|
180
|
+
if (handle.delegated)
|
|
181
|
+
stampDelegationDispatch(step, handle.delegated);
|
|
83
182
|
// Order-preserving by FIRST dispatch, counting every one after it: the count is what makes a
|
|
84
183
|
// gate's fourth fixer round visible, so a re-dispatch increments rather than deduplicating.
|
|
85
184
|
const dispatches = step.dispatches ?? [];
|
|
@@ -216,9 +315,320 @@ function stampToolServers(step, resolved, dispatchedKind) {
|
|
|
216
315
|
export function recordDispatchedJob(step, handle, dispatchedKind) {
|
|
217
316
|
step.jobId = handle.jobId;
|
|
218
317
|
recordDispatchAttribution(step, handle, dispatchedKind);
|
|
219
|
-
|
|
318
|
+
// A DELEGATED dispatch stamps no container, because there is none: the external executor owns
|
|
319
|
+
// the machine, and `recordDispatchAttribution` above has already moved its own record on.
|
|
320
|
+
// Stamping one anyway is what would make a delegated step render as a container that never
|
|
321
|
+
// reports a phase, an id or an address, and be addressed by the reclaim that kills containers
|
|
322
|
+
// by run.
|
|
323
|
+
if (!handle.delegated)
|
|
324
|
+
step.container = { status: 'up' };
|
|
220
325
|
return handle.jobId;
|
|
221
326
|
}
|
|
327
|
+
/**
|
|
328
|
+
* Open the delegation record for a dispatch about to happen: the CLAIM, committed BEFORE the
|
|
329
|
+
* external executor is called.
|
|
330
|
+
*
|
|
331
|
+
* This is the whole idempotency story for a delegated step, and the deadliest trap in the flow.
|
|
332
|
+
* Both durable drivers replay, and an executor asked to start twice produces two external runs and
|
|
333
|
+
* two pull requests for one task. So the engine takes the claim-before-effect half of the bargain
|
|
334
|
+
* the port asks the executor for: it writes `starting` with the correlation key as the step's job
|
|
335
|
+
* id, persists it, and only then dispatches. A replay finds the job id, re-attaches instead of
|
|
336
|
+
* dispatching, and the poll asks the executor to recover its own run by that key.
|
|
337
|
+
*
|
|
338
|
+
* The attempt log APPENDS. A re-run's earlier attempts and their URLs are the evidence for why the
|
|
339
|
+
* step is being re-run, and the platform holds nothing else about work that happened elsewhere.
|
|
340
|
+
* It does NOT append when the claim being re-opened is the SAME one, still unanswered: a dispatch
|
|
341
|
+
* that died between the claim and `start()` is re-driven under the same correlation key (see
|
|
342
|
+
* {@link liveJobId}), and the external system was asked once or not at all. Counted as a second
|
|
343
|
+
* attempt, a process that keeps dying would fill the step's evidence log with rounds that never
|
|
344
|
+
* reached anybody's runner.
|
|
345
|
+
*/
|
|
346
|
+
export function claimDelegation(step, input) {
|
|
347
|
+
const prior = step.delegated;
|
|
348
|
+
// A claim RESUMED rather than opened: same key, still unanswered, so this is the same attempt.
|
|
349
|
+
const resumed = prior?.status === 'starting' &&
|
|
350
|
+
prior.correlationKey === input.correlationKey &&
|
|
351
|
+
prior.attempts.length > 0;
|
|
352
|
+
step.jobId = input.correlationKey;
|
|
353
|
+
step.delegated = {
|
|
354
|
+
executor: input.executor,
|
|
355
|
+
status: 'starting',
|
|
356
|
+
correlationKey: input.correlationKey,
|
|
357
|
+
poll: input.poll,
|
|
358
|
+
externalId: null,
|
|
359
|
+
url: null,
|
|
360
|
+
phase: null,
|
|
361
|
+
attempts: resumed
|
|
362
|
+
? prior.attempts
|
|
363
|
+
: [...(prior?.attempts ?? []), { startedAt: input.startedAt }],
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
/** Fold an accepted dispatch onto the claim: the external id, the link, and the attempt it opened. */
|
|
367
|
+
function stampDelegationDispatch(step, delegated) {
|
|
368
|
+
// An accepted dispatch with no claim on the step cannot happen through `AgentDispatchController`
|
|
369
|
+
// (the claim is what commits before `start()`), but a HELPER dispatch site that forgot to claim
|
|
370
|
+
// would land here, and inventing a record is better than dropping the only link to the external
|
|
371
|
+
// run. `startedAt: 0` says the platform never saw this attempt begin.
|
|
372
|
+
const claim = step.delegated ?? {
|
|
373
|
+
executor: delegated.executor,
|
|
374
|
+
status: 'starting',
|
|
375
|
+
correlationKey: step.jobId ?? delegated.externalId,
|
|
376
|
+
// NO cadence, stated as absence. The executor's declaration is unreachable from here, and
|
|
377
|
+
// both ways of papering over it are worse than saying so: a number invented here would have
|
|
378
|
+
// the driver poll an external system on a figure nobody chose, and the zero window this used
|
|
379
|
+
// to write derived `maxPolls: NaN`, whose poll loop runs no iterations at all and fails the
|
|
380
|
+
// step as un-settled before the first poll. Absent, the driver uses the deployment's own job
|
|
381
|
+
// cadence (see `delegatedPollPolicy`).
|
|
382
|
+
poll: null,
|
|
383
|
+
attempts: [{ startedAt: 0 }],
|
|
384
|
+
};
|
|
385
|
+
const attempts = claim.attempts.length > 0 ? claim.attempts : [{ startedAt: 0 }];
|
|
386
|
+
step.delegated = {
|
|
387
|
+
...claim,
|
|
388
|
+
executor: delegated.executor,
|
|
389
|
+
status: 'running',
|
|
390
|
+
externalId: delegated.externalId,
|
|
391
|
+
url: delegated.url ?? claim.url ?? null,
|
|
392
|
+
// The branches and the TARGET repo the dispatch resolved. Persisted here, with the rest of the
|
|
393
|
+
// attribution, for the reason all of it is: the poll rebuilds its handle from the step alone.
|
|
394
|
+
...(delegated.branches ? { branches: delegated.branches } : {}),
|
|
395
|
+
...(delegated.repo ? { repo: delegated.repo } : {}),
|
|
396
|
+
attempts: attempts.map((attempt, index) => index === attempts.length - 1
|
|
397
|
+
? {
|
|
398
|
+
...attempt,
|
|
399
|
+
externalId: delegated.externalId,
|
|
400
|
+
url: delegated.url ?? attempt.url ?? null,
|
|
401
|
+
}
|
|
402
|
+
: attempt),
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Fold a dispatch that THREW onto the step's delegation claim, and drop the handle so the next
|
|
407
|
+
* advance dispatches rather than polls.
|
|
408
|
+
*
|
|
409
|
+
* The handle goes because the claim's job id says "there is an external run to poll", which after
|
|
410
|
+
* a throw is exactly what nobody knows. Cleared, a replayed advance re-dispatches under the SAME
|
|
411
|
+
* correlation key (the failed attempt recorded no dispatch, so the epoch has not moved) and the
|
|
412
|
+
* executor's own idempotency re-attaches to the run if one did start. Left set, the engine polls
|
|
413
|
+
* a job that may never have existed until the budget is spent and reports a timeout instead of
|
|
414
|
+
* the dispatch failure that actually happened.
|
|
415
|
+
*
|
|
416
|
+
* Whether the CLAIM survives is decided by the caller, and the two answers are different facts:
|
|
417
|
+
*
|
|
418
|
+
* - `contacted: false`: the dispatch failed before the executor's system was reached (no repo
|
|
419
|
+
* linked, no executor registered). Nothing is running anywhere, so the record SETTLES as
|
|
420
|
+
* failed, and a teardown that asked the executor to cancel would raise a false alarm about
|
|
421
|
+
* external work that never started.
|
|
422
|
+
* - `contacted: true`: the executor was called and the call threw. The run may be queued, may be
|
|
423
|
+
* running, may not exist; only the executor can tell. The claim stays OPEN so the teardown
|
|
424
|
+
* names it, asks the executor to cancel by correlation key, and records whether that worked.
|
|
425
|
+
* A settled record is invisible to `liveDelegations`, which is how a lost response left a live
|
|
426
|
+
* external run to finish and open a pull request on a task the board reported as failed.
|
|
427
|
+
*/
|
|
428
|
+
export function failDelegationDispatch(step, failure) {
|
|
429
|
+
step.jobId = undefined;
|
|
430
|
+
if (!step.delegated)
|
|
431
|
+
return;
|
|
432
|
+
if (!failure.contacted) {
|
|
433
|
+
settleDelegation(step, { status: 'failed', outcome: failure.error });
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
const attempts = step.delegated.attempts;
|
|
437
|
+
step.delegated = {
|
|
438
|
+
...step.delegated,
|
|
439
|
+
note: failure.error,
|
|
440
|
+
attempts: attempts.map((attempt, index) => index === attempts.length - 1 ? { ...attempt, outcome: failure.error } : attempt),
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Fold a RUNNING delegated poll onto the step, returning whether anything changed: the delegated
|
|
445
|
+
* sibling of {@link applyContainerRunning}.
|
|
446
|
+
*
|
|
447
|
+
* Separate from it rather than one fold over both, because the two records share no field beyond a
|
|
448
|
+
* status whose vocabularies differ. There is no container id to learn and no address to reach, and
|
|
449
|
+
* the two things that DO arrive late here (the external id and the URL, for a system that returns
|
|
450
|
+
* neither at start) have no counterpart there.
|
|
451
|
+
*
|
|
452
|
+
* The id is folded ONE WAY: a poll that reports none leaves the recorded one standing. An executor
|
|
453
|
+
* recovers its id once, and re-deriving it on every poll is what the fold exists to stop (the
|
|
454
|
+
* bounded correlation scan a busy repository eventually pushes the run off the end of).
|
|
455
|
+
*/
|
|
456
|
+
export function applyDelegationRunning(step, update) {
|
|
457
|
+
const prev = step.delegated;
|
|
458
|
+
// A running poll for a step with no record is a poll of work this engine never claimed. There is
|
|
459
|
+
// nothing to fold it onto, and inventing an executor id would be a guess.
|
|
460
|
+
if (!prev)
|
|
461
|
+
return false;
|
|
462
|
+
const next = {
|
|
463
|
+
...prev,
|
|
464
|
+
status: 'running',
|
|
465
|
+
externalId: update.externalId ?? prev.externalId ?? null,
|
|
466
|
+
url: update.url ?? prev.url ?? null,
|
|
467
|
+
phase: update.phase ?? prev.phase ?? null,
|
|
468
|
+
};
|
|
469
|
+
if (prev.status === next.status &&
|
|
470
|
+
(prev.externalId ?? null) === next.externalId &&
|
|
471
|
+
(prev.url ?? null) === next.url &&
|
|
472
|
+
(prev.phase ?? null) === next.phase) {
|
|
473
|
+
return false;
|
|
474
|
+
}
|
|
475
|
+
// The ATTEMPT this poll belongs to learns the same id, so the evidence log names the external
|
|
476
|
+
// run each round actually became rather than the correlation key it was dispatched under.
|
|
477
|
+
step.delegated = update.externalId
|
|
478
|
+
? { ...next, attempts: withLastAttempt(next.attempts, { externalId: update.externalId }) }
|
|
479
|
+
: next;
|
|
480
|
+
return true;
|
|
481
|
+
}
|
|
482
|
+
/** Fold a partial onto the LAST attempt, which is always the round in flight. */
|
|
483
|
+
function withLastAttempt(attempts, patch) {
|
|
484
|
+
return attempts.map((attempt, index) => index === attempts.length - 1 ? { ...attempt, ...patch } : attempt);
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Every DELEGATED unit this run still has running somewhere else, as the handles their executors
|
|
488
|
+
* address them by.
|
|
489
|
+
*
|
|
490
|
+
* Read over EVERY step rather than the current one: a run parks on one step at a time, but a
|
|
491
|
+
* delegated step that failed into a retry, or one the run advanced past while its external work
|
|
492
|
+
* was still winding down, is exactly the work a teardown must still name. A record that already
|
|
493
|
+
* settled is excluded, because asking an executor to cancel a finished run is a request it has no
|
|
494
|
+
* good answer to and the record would then claim a cancellation that did not happen.
|
|
495
|
+
*/
|
|
496
|
+
export function liveDelegations(instance,
|
|
497
|
+
/**
|
|
498
|
+
* The workspace the run belongs to. A PARAMETER, because an instance does not carry one and the
|
|
499
|
+
* handle requires it: the executor re-resolves its credentials to cancel, and a handle built
|
|
500
|
+
* with a placeholder resolves an empty bag, so every cancel fails on a missing credential and
|
|
501
|
+
* the record then reports work as possibly-still-running that the executor could have stopped.
|
|
502
|
+
* Taken here rather than patched on by the caller so there is nothing to forget.
|
|
503
|
+
*/
|
|
504
|
+
workspaceId) {
|
|
505
|
+
const handles = [];
|
|
506
|
+
for (const step of instance.steps) {
|
|
507
|
+
const record = step.delegated;
|
|
508
|
+
if (!record)
|
|
509
|
+
continue;
|
|
510
|
+
if (record.status !== 'starting' && record.status !== 'running')
|
|
511
|
+
continue;
|
|
512
|
+
handles.push({
|
|
513
|
+
executor: record.executor,
|
|
514
|
+
correlationKey: record.correlationKey,
|
|
515
|
+
...(record.externalId ? { externalId: record.externalId } : {}),
|
|
516
|
+
...(record.url ? { url: record.url } : {}),
|
|
517
|
+
...(record.branches ? { branches: record.branches } : {}),
|
|
518
|
+
...(record.repo ? { repo: record.repo } : {}),
|
|
519
|
+
workspaceId,
|
|
520
|
+
blockId: instance.blockId,
|
|
521
|
+
runId: instance.id,
|
|
522
|
+
agentKind: step.agentKind,
|
|
523
|
+
});
|
|
524
|
+
}
|
|
525
|
+
return handles;
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* Mark every live delegation `cancelled`, recording WHETHER the external work actually stopped.
|
|
529
|
+
*
|
|
530
|
+
* The distinction is the whole point. An executor that declares no `cancel` leaves its run alive:
|
|
531
|
+
* it will finish, open its pull request and bill its tokens long after the platform has recorded
|
|
532
|
+
* this run as stopped. Writing `cancelled` with nothing beside it would render a clean teardown
|
|
533
|
+
* over exactly that, and the person who stopped the run is the one who needs to know to go and
|
|
534
|
+
* stop it themselves.
|
|
535
|
+
*
|
|
536
|
+
* An unreported handle (the executor answered nothing) is treated as NOT cancelled, which is the
|
|
537
|
+
* fail-safe reading: "we asked" and "it stopped" are different facts and only the executor can
|
|
538
|
+
* turn the first into the second.
|
|
539
|
+
*/
|
|
540
|
+
export function applyDelegationCancellation(instance, report) {
|
|
541
|
+
const byKey = new Map((report ?? []).map((entry) => [entry.correlationKey, entry]));
|
|
542
|
+
let changed = false;
|
|
543
|
+
for (const step of instance.steps) {
|
|
544
|
+
const record = step.delegated;
|
|
545
|
+
if (!record)
|
|
546
|
+
continue;
|
|
547
|
+
if (record.status !== 'starting' && record.status !== 'running')
|
|
548
|
+
continue;
|
|
549
|
+
const outcome = byKey.get(record.correlationKey);
|
|
550
|
+
settleDelegation(step, {
|
|
551
|
+
status: 'cancelled',
|
|
552
|
+
outcome: outcome?.cancelled
|
|
553
|
+
? 'cancelled'
|
|
554
|
+
: 'cancel requested; the external run may still be running',
|
|
555
|
+
note: outcome?.note ??
|
|
556
|
+
(outcome?.cancelled
|
|
557
|
+
? undefined
|
|
558
|
+
: `This run was stopped, but "${record.executor}" could not stop the external work. ` +
|
|
559
|
+
'It may still be running, and opening a pull request; stop it there if that matters.'),
|
|
560
|
+
});
|
|
561
|
+
changed = true;
|
|
562
|
+
}
|
|
563
|
+
return changed;
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* Settle the delegation record on a terminal outcome, recording WHAT happened on the attempt the
|
|
567
|
+
* claim opened.
|
|
568
|
+
*
|
|
569
|
+
* `outcome` is the executor's own words rather than a platform classification, because this record
|
|
570
|
+
* is read by a person deciding whether to go and open the external logs, and "the workflow was
|
|
571
|
+
* cancelled upstream" tells them something `failed` does not.
|
|
572
|
+
*/
|
|
573
|
+
export function settleDelegation(step, settlement) {
|
|
574
|
+
const prev = step.delegated;
|
|
575
|
+
if (!prev)
|
|
576
|
+
return;
|
|
577
|
+
const attempts = prev.attempts;
|
|
578
|
+
step.delegated = {
|
|
579
|
+
...prev,
|
|
580
|
+
status: settlement.status,
|
|
581
|
+
...(settlement.url ? { url: settlement.url } : {}),
|
|
582
|
+
...(settlement.note ? { note: settlement.note } : {}),
|
|
583
|
+
...(settlement.branch ? { branch: settlement.branch } : {}),
|
|
584
|
+
attempts: attempts.map((attempt, index) => index === attempts.length - 1
|
|
585
|
+
? {
|
|
586
|
+
...attempt,
|
|
587
|
+
...(settlement.outcome ? { outcome: settlement.outcome } : {}),
|
|
588
|
+
...(settlement.url ? { url: settlement.url } : {}),
|
|
589
|
+
}
|
|
590
|
+
: attempt),
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* Settle the step's own DELEGATION on the job that just finished, whichever disposition it
|
|
595
|
+
* reached, or do nothing when the job that finished was not the delegated one.
|
|
596
|
+
*
|
|
597
|
+
* Its own function rather than a guard plus a call at the settle site, because the whole rule is
|
|
598
|
+
* the guard: the record outlives the work it describes (its attempt log is the evidence for a
|
|
599
|
+
* re-run), so a CONTAINER job run later on the same step would overwrite a `failed` or `cancelled`
|
|
600
|
+
* external outcome with `done`, and that record is the entire account of work that happened
|
|
601
|
+
* somewhere else.
|
|
602
|
+
*
|
|
603
|
+
* It takes the whole settled update, and BOTH dispositions, because a step's delegated job is not
|
|
604
|
+
* always its own work: a gate's `ci-fixer`, an `on-call`, a tester's `fixer` and a failed
|
|
605
|
+
* deployer's `deploy-fixer` all ride the same `step.jobId`, and the round they finish is routed
|
|
606
|
+
* away from the completion path entirely (see `SettledHelperRouter`). Settling only the success
|
|
607
|
+
* case, only on that path, left every delegated helper's record reading `running` for ever: the
|
|
608
|
+
* teardown then asks its executor to cancel a run that finished, the spend-gap fold skips it as
|
|
609
|
+
* still in flight, and the step card says "running externally" over a job that is long done.
|
|
610
|
+
*
|
|
611
|
+
* `branch` is folded here because it is the product of an executor that pushed without opening a
|
|
612
|
+
* pull request: a case the port names as legitimate, and one where dropping the branch settles the
|
|
613
|
+
* run as done with nothing to show for it.
|
|
614
|
+
*/
|
|
615
|
+
export function settleDelegatedJob(step, update) {
|
|
616
|
+
if (!inFlightDelegation(step))
|
|
617
|
+
return;
|
|
618
|
+
if (update.state === 'failed') {
|
|
619
|
+
settleDelegation(step, {
|
|
620
|
+
status: 'failed',
|
|
621
|
+
outcome: update.error,
|
|
622
|
+
...(update.delegated?.url ? { url: update.delegated.url } : {}),
|
|
623
|
+
});
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
settleDelegation(step, {
|
|
627
|
+
status: 'done',
|
|
628
|
+
...(update.delegated?.url ? { url: update.delegated.url } : {}),
|
|
629
|
+
...(update.delegated?.branch ? { branch: update.delegated.branch } : {}),
|
|
630
|
+
});
|
|
631
|
+
}
|
|
222
632
|
export function applyContainerRunning(step, update) {
|
|
223
633
|
const prev = step.container ?? undefined;
|
|
224
634
|
const next = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"step-fold.logic.js","sourceRoot":"","sources":["../../../src/modules/execution/step-fold.logic.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"step-fold.logic.js","sourceRoot":"","sources":["../../../src/modules/execution/step-fold.logic.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AgentKindRegistry } from '@cat-factory/agents';
|
|
2
|
-
import type { BinaryGeneratorRegistry, DeploymentDocumentResolver, FoundationalServiceRegistry, GateRegistry, InitiativePresetRegistry, InlineUseCaseRegistry, Logger, PipelineRegistry, PromptFragmentRegistry, PromptFragmentSource, TaskTypeRegistry } from '@cat-factory/kernel';
|
|
2
|
+
import type { BinaryGeneratorRegistry, DelegatedExecutorRegistry, DeploymentDocumentResolver, FoundationalServiceRegistry, GateRegistry, InitiativePresetRegistry, InlineUseCaseRegistry, Logger, PipelineRegistry, PromptFragmentRegistry, PromptFragmentSource, TaskTypeRegistry } from '@cat-factory/kernel';
|
|
3
3
|
/**
|
|
4
4
|
* A single problem found during validation. `error` aborts boot; `warn` is logged only, unless a
|
|
5
5
|
* deployment escalates it ({@link ValidateRegistrationsOptions.escalateWarning}).
|
|
@@ -104,6 +104,16 @@ interface ValidatedRegistries {
|
|
|
104
104
|
* a bad `formPanel`, or a `defaultPipelineId` naming a nonexistent pipeline fails at boot.
|
|
105
105
|
*/
|
|
106
106
|
taskTypeRegistry?: TaskTypeRegistry;
|
|
107
|
+
/**
|
|
108
|
+
* The app-owned DELEGATED-EXECUTOR registry to validate (the facade's injected instance, the
|
|
109
|
+
* SAME one it threads through `CoreDependencies.delegatedExecutorRegistry`). Optional: when
|
|
110
|
+
* omitted, a kind's `agent.executor` is still checked for PRESENCE (required on the delegated
|
|
111
|
+
* surface, refused on every other) but not for resolvability, because this process then has no
|
|
112
|
+
* set to resolve against and an empty one would report every id as missing. A facade passes it,
|
|
113
|
+
* so a kind naming an executor nobody registered fails at boot rather than on the first run of
|
|
114
|
+
* whichever pipeline reaches that step.
|
|
115
|
+
*/
|
|
116
|
+
delegatedExecutorRegistry?: DelegatedExecutorRegistry;
|
|
107
117
|
/**
|
|
108
118
|
* The app-owned inline use-case registry to validate (the facade's injected instance, the SAME
|
|
109
119
|
* one it threads through `CoreDependencies.inlineUseCaseRegistry`). Optional: when omitted, no
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validateRegistrations.d.ts","sourceRoot":"","sources":["../../src/validation/validateRegistrations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAI5D,OAAO,KAAK,EAEV,uBAAuB,EACvB,0BAA0B,EAC1B,2BAA2B,EAC3B,YAAY,EACZ,wBAAwB,EACxB,qBAAqB,EACrB,MAAM,EACN,gBAAgB,EAChB,sBAAsB,EACtB,oBAAoB,EACpB,gBAAgB,EACjB,MAAM,qBAAqB,CAAA;AAsD5B;;;;;;;GAOG;AACH,MAAM,MAAM,mBAAmB,GAAG,wBAAwB,GAAG,mBAAmB,CAAA;AAEhF;;;;;;;GAOG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,OAAO,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,uBAAuB,YAClC,0BAA0B,EAC1B,mCAAmC,EACnC,4BAA4B,EAC5B,gCAAgC,EAChC,uBAAuB,EACvB,+BAA+B,EAC/B,wBAAwB,EACxB,wBAAwB,EACxB,4BAA4B,CACpB,CAAA;AAEV,8CAA8C;AAC9C,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAA;AAE3E;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,oBAAoB,CAAA;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;;;;;;GAYG;AACH,UAAU,mBAAmB;IAC3B;;;OAGG;IACH,iBAAiB,EAAE,iBAAiB,CAAA;IACpC;;;;OAIG;IACH,YAAY,EAAE,YAAY,CAAA;IAC1B;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;IACnC;;;;;;OAMG;IACH,qBAAqB,CAAC,EAAE,qBAAqB,CAAA;IAC7C;;;;;OAKG;IACH,wBAAwB,CAAC,EAAE,wBAAwB,CAAA;IACnD;;;;;;OAMG;IACH,2BAA2B,CAAC,EAAE,2BAA2B,CAAA;IACzD;;;;;;OAMG;IACH,uBAAuB,CAAC,EAAE,uBAAuB,CAAA;IACjD;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,sBAAsB,CAAA;IAC/C;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,oBAAoB,CAAA;IACtC;;;;;;;OAOG;IACH,0BAA0B,CAAC,EAAE,0BAA0B,CAAA;CACxD;AAED,uFAAuF;AACvF,MAAM,WAAW,4BAA4B;IAC3C,+EAA+E;IAC/E,UAAU,EAAE,mBAAmB,CAAA;IAC/B,qGAAqG;IACrG,kBAAkB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACxC,qGAAqG;IACrG,kBAAkB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACxC;;;;;OAKG;IACH,eAAe,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACrC;;;;OAIG;IACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,CAAA;IAC/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoCG;IACH,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,OAAO,CAAA;CAC5D;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,4BAA4B,GACjC,mBAAmB,EAAE,
|
|
1
|
+
{"version":3,"file":"validateRegistrations.d.ts","sourceRoot":"","sources":["../../src/validation/validateRegistrations.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { INLINE_ENGINE_SYSTEM_PROMPTS, runsInContainer } from '@cat-factory/agents';
|
|
1
|
+
import { INLINE_ENGINE_SYSTEM_PROMPTS, runsInContainer, surfaceTraits } from '@cat-factory/agents';
|
|
2
2
|
import { checkBinaryGenerators } from './validateBinaryGenerators.js';
|
|
3
3
|
import { inlineUseCaseProblems } from './validateInlineUseCases.js';
|
|
4
4
|
import { CI_FIXER_AGENT_KIND, CONFLICT_RESOLVER_AGENT_KIND, FIXER_AGENT_KIND, ON_CALL_AGENT_KIND, describeFoundationalProblem, getErrorMessage, seedPipelines, stubGateContext, validateFoundationalDefinition, } from '@cat-factory/kernel';
|
|
@@ -121,6 +121,9 @@ export function collectRegistrationProblems(opts) {
|
|
|
121
121
|
problems.push(...checkAgentCapabilities(registry));
|
|
122
122
|
// 7b. A kind's declared IMAGE VARIANT: a slug, and never a platform name it may not claim.
|
|
123
123
|
problems.push(...checkAgentImageVariants(registry));
|
|
124
|
+
// 7c. A kind's declared DELEGATED EXECUTOR: required on that surface, refused on every other,
|
|
125
|
+
// and resolvable in this build.
|
|
126
|
+
problems.push(...checkDelegatedExecutors(opts, registry));
|
|
124
127
|
// 7. Agent-kind VARIANTS: their base kind must exist and they must actually change the prompt.
|
|
125
128
|
problems.push(...checkAgentKindVariants(opts, registeredKindIds));
|
|
126
129
|
// 8. Deployment-registered FOUNDATIONAL SERVICES (only when a registry is supplied).
|
|
@@ -334,6 +337,88 @@ function checkAgentImageVariants(registry) {
|
|
|
334
337
|
}
|
|
335
338
|
return problems;
|
|
336
339
|
}
|
|
340
|
+
/**
|
|
341
|
+
* A registered kind's DELEGATED EXECUTOR (`AgentStepSpec.executor`): the declaration that says the
|
|
342
|
+
* step's work leaves the platform.
|
|
343
|
+
*
|
|
344
|
+
* Three faults, and all three are silent at run time in different ways, which is why boot grades
|
|
345
|
+
* each rather than letting the dispatch discover them:
|
|
346
|
+
*
|
|
347
|
+
* - a `delegated` kind with NO executor has nowhere to dispatch. The dispatch throws, hours into
|
|
348
|
+
* whichever pipeline reached the step first, with a message about a registration nobody was
|
|
349
|
+
* looking at.
|
|
350
|
+
* - a NON-delegated kind carrying one is the opposite error and the more dangerous: the
|
|
351
|
+
* declaration is read by nothing, so the deployment believes a step runs on its own CI while
|
|
352
|
+
* every run of it quietly goes through the platform's harness. Refused rather than warned,
|
|
353
|
+
* because there is no reading of it under which it does something.
|
|
354
|
+
* - an executor id this build does not register can never be resolved. Graded only when the
|
|
355
|
+
* facade supplied its registry, for the reason every other cross-registry check is: an absent
|
|
356
|
+
* registry is "we cannot see the set", not "the set is empty".
|
|
357
|
+
*/
|
|
358
|
+
function checkDelegatedExecutors(opts, registry) {
|
|
359
|
+
const executors = opts.registries.delegatedExecutorRegistry;
|
|
360
|
+
const problems = [];
|
|
361
|
+
for (const definition of registry.all()) {
|
|
362
|
+
const step = definition.agent;
|
|
363
|
+
if (!step)
|
|
364
|
+
continue;
|
|
365
|
+
// Through the accessor, never the table directly. `SURFACE_TRAITS` is total over the surfaces
|
|
366
|
+
// THIS build knows, and a registration can name one it does not: a mothership-mode node
|
|
367
|
+
// resolves kinds from a process that may be a build ahead, and nothing boot-validates them
|
|
368
|
+
// there. Indexed bare, that is a `TypeError` thrown INSIDE the function whose whole job is to
|
|
369
|
+
// report a bad registration, so the boot that was meant to name the offending kind dies
|
|
370
|
+
// instead, naming nothing.
|
|
371
|
+
const traits = surfaceTraits(step.surface);
|
|
372
|
+
if (!traits) {
|
|
373
|
+
problems.push({
|
|
374
|
+
severity: 'error',
|
|
375
|
+
code: 'agent_surface_unknown',
|
|
376
|
+
message: `Agent kind "${definition.kind}" declares the agent surface "${step.surface}", which ` +
|
|
377
|
+
`this build does not recognise, so nothing can be concluded about how it runs: whether ` +
|
|
378
|
+
`it needs a checkout, whether its reply is its product, or whether its work leaves the ` +
|
|
379
|
+
`platform. Name a surface this build ships, or upgrade the deployment that defines it.`,
|
|
380
|
+
});
|
|
381
|
+
continue;
|
|
382
|
+
}
|
|
383
|
+
const delegated = traits.delegated;
|
|
384
|
+
if (!delegated) {
|
|
385
|
+
if (step.executor !== undefined) {
|
|
386
|
+
problems.push({
|
|
387
|
+
severity: 'error',
|
|
388
|
+
code: 'agent_executor_on_non_delegated_surface',
|
|
389
|
+
message: `Agent kind "${definition.kind}" declares the delegated executor ` +
|
|
390
|
+
`"${step.executor}" on the "${step.surface}" surface, where nothing reads it. ` +
|
|
391
|
+
`A kind whose work runs on an external executor declares \`surface: 'delegated'\`; ` +
|
|
392
|
+
`otherwise remove the executor, because leaving it reads as a step that leaves the ` +
|
|
393
|
+
`platform when every run of it goes through the harness.`,
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
continue;
|
|
397
|
+
}
|
|
398
|
+
if (!step.executor) {
|
|
399
|
+
problems.push({
|
|
400
|
+
severity: 'error',
|
|
401
|
+
code: 'agent_executor_missing',
|
|
402
|
+
message: `Agent kind "${definition.kind}" declares the "delegated" surface and names no ` +
|
|
403
|
+
`executor, so a dispatch of it has nowhere to go. Name a registered ` +
|
|
404
|
+
`DelegatedExecutorDefinition id on \`agent.executor\`.`,
|
|
405
|
+
});
|
|
406
|
+
continue;
|
|
407
|
+
}
|
|
408
|
+
if (!executors)
|
|
409
|
+
continue;
|
|
410
|
+
if (!executors.get(step.executor)) {
|
|
411
|
+
problems.push({
|
|
412
|
+
severity: 'error',
|
|
413
|
+
code: 'agent_executor_unknown',
|
|
414
|
+
message: `Agent kind "${definition.kind}" runs on the delegated executor ` +
|
|
415
|
+
`"${step.executor}", which this deployment does not register` +
|
|
416
|
+
(executors.size > 0 ? ` (registered: ${executors.ids().join(', ')}).` : '.'),
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
return problems;
|
|
421
|
+
}
|
|
337
422
|
/**
|
|
338
423
|
* Section 7 of {@link collectRegistrationProblems}: every registered agent-kind VARIANT must vary
|
|
339
424
|
* a kind that exists and must change something.
|