@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.
Files changed (119) hide show
  1. package/dist/container/dependencies.d.ts +10 -1
  2. package/dist/container/dependencies.d.ts.map +1 -1
  3. package/dist/container/execution-service.d.ts.map +1 -1
  4. package/dist/container/execution-service.js +1 -0
  5. package/dist/container/execution-service.js.map +1 -1
  6. package/dist/container/runtime.d.ts +1 -0
  7. package/dist/container/runtime.d.ts.map +1 -1
  8. package/dist/container/runtime.js +5 -1
  9. package/dist/container/runtime.js.map +1 -1
  10. package/dist/container.d.ts +8 -1
  11. package/dist/container.d.ts.map +1 -1
  12. package/dist/container.js +2 -1
  13. package/dist/container.js.map +1 -1
  14. package/dist/index.d.ts +1 -0
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +5 -0
  17. package/dist/index.js.map +1 -1
  18. package/dist/modules/debug/RunDebugService.d.ts.map +1 -1
  19. package/dist/modules/debug/RunDebugService.js +20 -2
  20. package/dist/modules/debug/RunDebugService.js.map +1 -1
  21. package/dist/modules/debug/llmReporting.logic.d.ts +24 -0
  22. package/dist/modules/debug/llmReporting.logic.d.ts.map +1 -0
  23. package/dist/modules/debug/llmReporting.logic.js +35 -0
  24. package/dist/modules/debug/llmReporting.logic.js.map +1 -0
  25. package/dist/modules/execution/AgentDispatchController.d.ts +7 -0
  26. package/dist/modules/execution/AgentDispatchController.d.ts.map +1 -1
  27. package/dist/modules/execution/AgentDispatchController.js +40 -24
  28. package/dist/modules/execution/AgentDispatchController.js.map +1 -1
  29. package/dist/modules/execution/DeployFixController.d.ts +9 -0
  30. package/dist/modules/execution/DeployFixController.d.ts.map +1 -1
  31. package/dist/modules/execution/DeployFixController.js +10 -10
  32. package/dist/modules/execution/DeployFixController.js.map +1 -1
  33. package/dist/modules/execution/DeployerStepController.d.ts.map +1 -1
  34. package/dist/modules/execution/DeployerStepController.js +4 -3
  35. package/dist/modules/execution/DeployerStepController.js.map +1 -1
  36. package/dist/modules/execution/ExecutionService.d.ts +7 -0
  37. package/dist/modules/execution/ExecutionService.d.ts.map +1 -1
  38. package/dist/modules/execution/ExecutionService.js +17 -0
  39. package/dist/modules/execution/ExecutionService.js.map +1 -1
  40. package/dist/modules/execution/ExecutionServiceDependencies.d.ts +8 -1
  41. package/dist/modules/execution/ExecutionServiceDependencies.d.ts.map +1 -1
  42. package/dist/modules/execution/GateHelperDispatcher.d.ts +8 -0
  43. package/dist/modules/execution/GateHelperDispatcher.d.ts.map +1 -1
  44. package/dist/modules/execution/GateHelperDispatcher.js +9 -5
  45. package/dist/modules/execution/GateHelperDispatcher.js.map +1 -1
  46. package/dist/modules/execution/GateStepController.d.ts.map +1 -1
  47. package/dist/modules/execution/GateStepController.js +9 -3
  48. package/dist/modules/execution/GateStepController.js.map +1 -1
  49. package/dist/modules/execution/HumanTestController.d.ts +7 -0
  50. package/dist/modules/execution/HumanTestController.d.ts.map +1 -1
  51. package/dist/modules/execution/HumanTestController.js +20 -8
  52. package/dist/modules/execution/HumanTestController.js.map +1 -1
  53. package/dist/modules/execution/OneShotStepController.d.ts +1 -1
  54. package/dist/modules/execution/OneShotStepController.js +1 -1
  55. package/dist/modules/execution/PollCompletionController.d.ts +22 -3
  56. package/dist/modules/execution/PollCompletionController.d.ts.map +1 -1
  57. package/dist/modules/execution/PollCompletionController.js +78 -8
  58. package/dist/modules/execution/PollCompletionController.js.map +1 -1
  59. package/dist/modules/execution/PollRunningController.d.ts +22 -7
  60. package/dist/modules/execution/PollRunningController.d.ts.map +1 -1
  61. package/dist/modules/execution/PollRunningController.js +64 -13
  62. package/dist/modules/execution/PollRunningController.js.map +1 -1
  63. package/dist/modules/execution/RalphController.d.ts +7 -0
  64. package/dist/modules/execution/RalphController.d.ts.map +1 -1
  65. package/dist/modules/execution/RalphController.js +12 -8
  66. package/dist/modules/execution/RalphController.js.map +1 -1
  67. package/dist/modules/execution/RunDispatcher.d.ts.map +1 -1
  68. package/dist/modules/execution/RunDispatcher.js +19 -6
  69. package/dist/modules/execution/RunDispatcher.js.map +1 -1
  70. package/dist/modules/execution/RunDispatcherDependencies.d.ts +16 -1
  71. package/dist/modules/execution/RunDispatcherDependencies.d.ts.map +1 -1
  72. package/dist/modules/execution/RunDispatcherDependencies.js.map +1 -1
  73. package/dist/modules/execution/RunStateMachine.d.ts.map +1 -1
  74. package/dist/modules/execution/RunStateMachine.js +21 -2
  75. package/dist/modules/execution/RunStateMachine.js.map +1 -1
  76. package/dist/modules/execution/StepGraph.d.ts.map +1 -1
  77. package/dist/modules/execution/StepGraph.js +7 -0
  78. package/dist/modules/execution/StepGraph.js.map +1 -1
  79. package/dist/modules/execution/TesterController.d.ts +7 -0
  80. package/dist/modules/execution/TesterController.d.ts.map +1 -1
  81. package/dist/modules/execution/TesterController.js +24 -18
  82. package/dist/modules/execution/TesterController.js.map +1 -1
  83. package/dist/modules/execution/VisualConfirmationController.d.ts +7 -0
  84. package/dist/modules/execution/VisualConfirmationController.d.ts.map +1 -1
  85. package/dist/modules/execution/VisualConfirmationController.js +20 -8
  86. package/dist/modules/execution/VisualConfirmationController.js.map +1 -1
  87. package/dist/modules/execution/advance.d.ts +14 -0
  88. package/dist/modules/execution/advance.d.ts.map +1 -1
  89. package/dist/modules/execution/awaitingJob.logic.d.ts +30 -0
  90. package/dist/modules/execution/awaitingJob.logic.d.ts.map +1 -0
  91. package/dist/modules/execution/awaitingJob.logic.js +62 -0
  92. package/dist/modules/execution/awaitingJob.logic.js.map +1 -0
  93. package/dist/modules/execution/delegation.logic.d.ts +93 -0
  94. package/dist/modules/execution/delegation.logic.d.ts.map +1 -0
  95. package/dist/modules/execution/delegation.logic.js +97 -0
  96. package/dist/modules/execution/delegation.logic.js.map +1 -0
  97. package/dist/modules/execution/deployer-family.d.ts.map +1 -1
  98. package/dist/modules/execution/deployer-family.js +1 -0
  99. package/dist/modules/execution/deployer-family.js.map +1 -1
  100. package/dist/modules/execution/drive.d.ts.map +1 -1
  101. package/dist/modules/execution/drive.js +6 -1
  102. package/dist/modules/execution/drive.js.map +1 -1
  103. package/dist/modules/execution/gate-window-controllers.d.ts +7 -0
  104. package/dist/modules/execution/gate-window-controllers.d.ts.map +1 -1
  105. package/dist/modules/execution/gate-window-controllers.js +5 -1
  106. package/dist/modules/execution/gate-window-controllers.js.map +1 -1
  107. package/dist/modules/execution/job.logic.d.ts +38 -2
  108. package/dist/modules/execution/job.logic.d.ts.map +1 -1
  109. package/dist/modules/execution/job.logic.js +34 -0
  110. package/dist/modules/execution/job.logic.js.map +1 -1
  111. package/dist/modules/execution/step-fold.logic.d.ts +218 -2
  112. package/dist/modules/execution/step-fold.logic.d.ts.map +1 -1
  113. package/dist/modules/execution/step-fold.logic.js +413 -3
  114. package/dist/modules/execution/step-fold.logic.js.map +1 -1
  115. package/dist/validation/validateRegistrations.d.ts +11 -1
  116. package/dist/validation/validateRegistrations.d.ts.map +1 -1
  117. package/dist/validation/validateRegistrations.js +86 -1
  118. package/dist/validation/validateRegistrations.js.map +1 -1
  119. 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
- step.container = { status: 'up' };
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":"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"}
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.