@cat-factory/orchestration 0.37.0 → 0.37.2

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 (33) hide show
  1. package/dist/modules/execution/CompanionController.d.ts +6 -11
  2. package/dist/modules/execution/CompanionController.d.ts.map +1 -1
  3. package/dist/modules/execution/CompanionController.js +20 -20
  4. package/dist/modules/execution/CompanionController.js.map +1 -1
  5. package/dist/modules/execution/ExecutionService.d.ts +5 -151
  6. package/dist/modules/execution/ExecutionService.d.ts.map +1 -1
  7. package/dist/modules/execution/ExecutionService.js +103 -578
  8. package/dist/modules/execution/ExecutionService.js.map +1 -1
  9. package/dist/modules/execution/HumanTestController.d.ts +6 -8
  10. package/dist/modules/execution/HumanTestController.d.ts.map +1 -1
  11. package/dist/modules/execution/HumanTestController.js +26 -26
  12. package/dist/modules/execution/HumanTestController.js.map +1 -1
  13. package/dist/modules/execution/ReviewGateController.d.ts +11 -19
  14. package/dist/modules/execution/ReviewGateController.d.ts.map +1 -1
  15. package/dist/modules/execution/ReviewGateController.js +19 -19
  16. package/dist/modules/execution/ReviewGateController.js.map +1 -1
  17. package/dist/modules/execution/RunStateMachine.d.ts +131 -0
  18. package/dist/modules/execution/RunStateMachine.d.ts.map +1 -0
  19. package/dist/modules/execution/RunStateMachine.js +389 -0
  20. package/dist/modules/execution/RunStateMachine.js.map +1 -0
  21. package/dist/modules/execution/StepGraph.d.ts +70 -0
  22. package/dist/modules/execution/StepGraph.d.ts.map +1 -0
  23. package/dist/modules/execution/StepGraph.js +124 -0
  24. package/dist/modules/execution/StepGraph.js.map +1 -0
  25. package/dist/modules/execution/TesterController.d.ts +3 -4
  26. package/dist/modules/execution/TesterController.d.ts.map +1 -1
  27. package/dist/modules/execution/TesterController.js +6 -6
  28. package/dist/modules/execution/TesterController.js.map +1 -1
  29. package/dist/modules/execution/VisualConfirmationController.d.ts +6 -8
  30. package/dist/modules/execution/VisualConfirmationController.d.ts.map +1 -1
  31. package/dist/modules/execution/VisualConfirmationController.js +18 -18
  32. package/dist/modules/execution/VisualConfirmationController.js.map +1 -1
  33. package/package.json +1 -1
@@ -0,0 +1,389 @@
1
+ import { isAsyncAgentExecutor } from '@cat-factory/kernel';
2
+ import { MERGER_AGENT_KIND } from './ci.logic.js';
3
+ /**
4
+ * "What to do next" guidance per failure kind a pipeline run can produce, shown
5
+ * under the failure banner on the board (mirrors bootstrap's FAILURE_HINTS). Only
6
+ * the execution-relevant subset of {@link AgentFailureKind} is keyed.
7
+ */
8
+ const EXECUTION_FAILURE_HINTS = {
9
+ agent: 'An agent step failed after its automatic retries. Review the run, then retry to re-run the pipeline.',
10
+ job_failed: 'The implementation container reported a failure. Inspect its logs (Cloudflare Workers Observability, filtered by the run id), then retry to spin a fresh container.',
11
+ evicted: 'The implementation container kept vanishing mid-run even after automatic fresh-container restarts. Most often this is transient: a deploy / new-version rollout draining the container, in which case simply retrying once the rollout has finished succeeds. If it persists, it points at a memory or crash issue on the run — inspect its logs (Cloudflare Workers Observability, filtered by the run id) and consider a heavier container instance type. Retry to try again.',
12
+ timeout: 'The run exceeded its time budget — a step or the implementation job did not finish in time. Retry to start it again.',
13
+ rejected: 'You rejected this step’s proposal, stopping the run. Retry to re-run the pipeline from the rejected step.',
14
+ companion_rejected: 'A companion agent could not return a usable quality assessment (its reply was truncated or malformed) even after a repair retry. Review the companion’s raw output on the run, then retry.',
15
+ cancelled: 'You stopped this run; its container was killed. Retry to start it again.',
16
+ dispatch: 'The agent’s container could not be started — the run never began executing. The provider/runtime’s verbatim response is shown below. Most often this is transient (a capacity blip or a new-version rollout); retrying spins a fresh container. If it persists it points at a misconfigured container binding/image or runner pool. Retry to try again.',
17
+ unknown: 'The run failed for an unclassified reason. Review the run, then retry.',
18
+ };
19
+ /**
20
+ * The async instance/block state-machine spine of the execution engine — the outer layer
21
+ * over {@link StepGraph}. It owns everything the engine and every gate controller share
22
+ * about MOVING a run: persisting the instance, pushing the live event (with the metrics
23
+ * rollup + terminal-state cleanup), the block status/progress writes, parking on a decision
24
+ * and advancing past a resolved one, finalizing a finished pipeline, failing a run, and
25
+ * reclaiming the per-run container.
26
+ *
27
+ * Lifted verbatim out of `ExecutionService` so these primitives have ONE cohesive home
28
+ * instead of being scattered as private methods and handed to each controller as a fat
29
+ * callback bag. The merge/auto-start subgraph (`finalizeMerge` / `applyModuleAssignment` /
30
+ * `autoStartDependents`) deliberately stays on the engine — `finalizeBlock` here only flips
31
+ * status and raises the no-merger notification, so this layer carries no merge collaborators.
32
+ */
33
+ export class RunStateMachine {
34
+ executionRepository;
35
+ blockRepository;
36
+ events;
37
+ workRunner;
38
+ agentExecutor;
39
+ idGenerator;
40
+ clock;
41
+ stepGraph;
42
+ notificationService;
43
+ kaizenScheduler;
44
+ subscriptionActivations;
45
+ llmObservability;
46
+ constructor(deps) {
47
+ this.executionRepository = deps.executionRepository;
48
+ this.blockRepository = deps.blockRepository;
49
+ this.events = deps.events;
50
+ this.workRunner = deps.workRunner;
51
+ this.agentExecutor = deps.agentExecutor;
52
+ this.idGenerator = deps.idGenerator;
53
+ this.clock = deps.clock;
54
+ this.stepGraph = deps.stepGraph;
55
+ this.notificationService = deps.notificationService;
56
+ this.kaizenScheduler = deps.kaizenScheduler;
57
+ this.subscriptionActivations = deps.subscriptionActivations;
58
+ this.llmObservability = deps.llmObservability;
59
+ }
60
+ /** Persist the instance (the single write seam shared by the engine + controllers). */
61
+ persistInstance(workspaceId, instance) {
62
+ return this.executionRepository.upsert(workspaceId, instance);
63
+ }
64
+ async emitInstance(workspaceId, instance) {
65
+ // Stamp each step with the run id so a lone step (in a pushed event, a log line, a
66
+ // detail view) is self-describing for debugging; the value always equals the run id.
67
+ for (const step of instance.steps)
68
+ step.runId = instance.id;
69
+ // The metrics rollup and the block fetch are independent, so run them concurrently
70
+ // — the rollup adds no serial latency to the (frequent) emit path.
71
+ const [, block] = await Promise.all([
72
+ this.attachStepMetrics(workspaceId, instance),
73
+ this.blockRepository.get(workspaceId, instance.blockId),
74
+ ]);
75
+ await this.events.executionChanged(workspaceId, instance, block);
76
+ // When a run reaches a terminal state, schedule a post-run Kaizen grading for each
77
+ // completed agent step (the scheduler skips verified combos + already-graded steps).
78
+ // Best-effort + idempotent: a failure here must never derail the emit, and a re-emit
79
+ // of an already-scheduled run is a no-op. The actual LLM grading runs later in the
80
+ // background sweep, so this only does cheap inserts.
81
+ if (this.kaizenScheduler && (instance.status === 'done' || instance.status === 'failed')) {
82
+ try {
83
+ await this.kaizenScheduler.scheduleForRun(workspaceId, instance);
84
+ }
85
+ catch {
86
+ // Swallow — grading is an observability concern and must never break a run.
87
+ }
88
+ }
89
+ // When a run reaches a terminal state, delete its per-run personal-credential
90
+ // activation immediately (individual-usage subscriptions) so the system-encrypted
91
+ // token copy doesn't linger to its TTL. Best-effort + idempotent — a missing repo or
92
+ // a re-emit of an already-cleared run is a no-op, and a failure here must never
93
+ // derail the emit.
94
+ if (this.subscriptionActivations &&
95
+ (instance.status === 'done' || instance.status === 'failed')) {
96
+ try {
97
+ await this.subscriptionActivations.deleteByExecution(instance.id);
98
+ }
99
+ catch {
100
+ // Swallow — a failure here must never derail the emit. This is not a silent
101
+ // data-loss path: the TTL sweep reclaims the row as a backstop, and the sweep
102
+ // (Worker cron / Node retention timer) logs its own errors, so a *systemic*
103
+ // cleanup failure surfaces there rather than being lost here.
104
+ }
105
+ }
106
+ }
107
+ /**
108
+ * Roll the run's recorded LLM calls into per-step `metrics` for the board, in
109
+ * place on the emitted instance. The proxy keys calls by execution + agentKind
110
+ * (not step index), so the aggregate is per-agent-kind within the run; steps
111
+ * sharing a kind get the same rollup. Best-effort and a no-op when the sink is
112
+ * not wired, so it never blocks an emit.
113
+ */
114
+ async attachStepMetrics(workspaceId, instance) {
115
+ if (!this.llmObservability)
116
+ return;
117
+ try {
118
+ const summaries = await this.llmObservability.summarizeByExecution(workspaceId, instance.id);
119
+ if (summaries.length === 0)
120
+ return;
121
+ const byKind = new Map(summaries.map((s) => [s.agentKind, s]));
122
+ for (const step of instance.steps) {
123
+ const s = byKind.get(step.agentKind);
124
+ if (!s)
125
+ continue;
126
+ step.metrics = {
127
+ calls: s.calls,
128
+ promptTokens: s.promptTokens,
129
+ cachedPromptTokens: s.cachedPromptTokens,
130
+ completionTokens: s.completionTokens,
131
+ peakCompletionTokens: s.peakCompletionTokens,
132
+ maxOutputTokens: s.maxOutputTokens,
133
+ truncatedCalls: s.truncatedCalls,
134
+ upstreamMs: s.upstreamMs,
135
+ overheadMs: s.overheadMs,
136
+ errors: s.errors,
137
+ warnings: s.warnings,
138
+ };
139
+ }
140
+ }
141
+ catch (error) {
142
+ // Observability is best-effort; never block an emit on a metrics read.
143
+ void error;
144
+ }
145
+ }
146
+ /** Set the block's in-progress/blocked status and step-completion progress. */
147
+ async updateBlockProgress(workspaceId, instance, status) {
148
+ const total = instance.steps.length || 1;
149
+ const done = instance.steps.filter((s) => s.state === 'done').length;
150
+ await this.blockRepository.update(workspaceId, instance.blockId, {
151
+ status,
152
+ progress: Math.min(1, done / total),
153
+ });
154
+ }
155
+ /**
156
+ * Advance the block's step PROGRESS without touching its status — used when a step
157
+ * resolver already owns the block's terminal status (the merger set `done`/`pr_ready`)
158
+ * and a trailing step still follows, so the bar moves on without downgrading that status.
159
+ */
160
+ async refreshBlockProgress(workspaceId, instance) {
161
+ const total = instance.steps.length || 1;
162
+ const done = instance.steps.filter((s) => s.state === 'done').length;
163
+ await this.blockRepository.update(workspaceId, instance.blockId, {
164
+ progress: Math.min(1, done / total),
165
+ });
166
+ }
167
+ /**
168
+ * Park a step on a human approval decision: mint the approval id, freeze the step's
169
+ * duration clock, flip the run `blocked`, persist + emit, and return the durable
170
+ * `awaiting_decision` outcome the driver parks on.
171
+ */
172
+ async parkStepOnDecision(workspaceId, instance, step, proposal = '') {
173
+ step.approval = { id: this.idGenerator.next('appr'), status: 'pending', proposal };
174
+ this.stepGraph.pauseStepForInput(step);
175
+ instance.status = 'blocked';
176
+ await this.updateBlockProgress(workspaceId, instance, 'blocked');
177
+ await this.executionRepository.upsert(workspaceId, instance);
178
+ await this.emitInstance(workspaceId, instance);
179
+ return { kind: 'awaiting_decision', decisionId: step.approval.id };
180
+ }
181
+ /**
182
+ * Finish a gate step whose decision a human resolved and advance the run: stamp the step
183
+ * done, finalize the block (final step) or start the next, persist, signal the durable
184
+ * driver that the decision is `approved`, and emit.
185
+ */
186
+ async advancePastResolvedGate(workspaceId, instance, stepIndex) {
187
+ const step = instance.steps[stepIndex];
188
+ const decisionId = step.approval.id;
189
+ this.stepGraph.finishStep(step);
190
+ step.progress = 1;
191
+ const isFinalStep = stepIndex === instance.steps.length - 1;
192
+ if (isFinalStep) {
193
+ instance.status = 'done';
194
+ await this.finalizeBlock(workspaceId, instance, undefined);
195
+ await this.stopRunContainer(workspaceId, instance);
196
+ }
197
+ else {
198
+ instance.currentStep = stepIndex + 1;
199
+ const next = instance.steps[instance.currentStep];
200
+ if (next)
201
+ this.stepGraph.startStep(next);
202
+ if (instance.status === 'blocked')
203
+ instance.status = 'running';
204
+ await this.updateBlockProgress(workspaceId, instance, 'in_progress');
205
+ }
206
+ await this.executionRepository.upsert(workspaceId, instance);
207
+ await this.workRunner.signalDecision(workspaceId, instance.id, decisionId, 'approved');
208
+ await this.emitInstance(workspaceId, instance);
209
+ }
210
+ /**
211
+ * A pipeline finished. A frame becomes `done` (a mapping-only run leaves it
212
+ * `ready`). A *task* never auto-`done`s from a confidence score any more — that
213
+ * looked merged when the PR was still open with red CI. Instead:
214
+ * - if the pipeline has a `merger` step, it already owned the merge/notify
215
+ * decision (see `resolveMergerStep`); we only backstop a missing one;
216
+ * - otherwise the work is complete but unmerged: leave the PR open (`pr_ready`)
217
+ * and raise a `pipeline_complete` notification for a human to confirm + merge.
218
+ * `done` now strictly means the PR was merged (see the engine's `finalizeMerge`).
219
+ */
220
+ async finalizeBlock(workspaceId, instance, confidence) {
221
+ const block = await this.blockRepository.get(workspaceId, instance.blockId);
222
+ if (!block || block.status === 'done')
223
+ return;
224
+ if ((block.level ?? 'frame') !== 'task') {
225
+ // A mapping-only run (just the `blueprints` step, e.g. kicked off after a
226
+ // bootstrap) leaves the service frame `ready` and droppable rather than
227
+ // marking the whole service "done".
228
+ const mappingOnly = instance.steps.every((s) => s.agentKind === 'blueprints');
229
+ await this.blockRepository.update(workspaceId, block.id, {
230
+ status: mappingOnly ? 'ready' : 'done',
231
+ progress: 1,
232
+ });
233
+ return;
234
+ }
235
+ // Confidence is recorded by the caller (recordStepResult) before any merge, so
236
+ // it persists on both the merge and review paths; `confidence` is unused here.
237
+ void confidence;
238
+ const hasMerger = instance.steps.some((s) => s.agentKind === MERGER_AGENT_KIND);
239
+ if (hasMerger) {
240
+ // The `merger` step already merged (→ `done`) or raised a review (→ `pr_ready`).
241
+ // Only backstop the case where it produced no decision at all.
242
+ const fresh = await this.blockRepository.get(workspaceId, block.id);
243
+ if (fresh && fresh.status !== 'done' && fresh.status !== 'pr_ready') {
244
+ await this.blockRepository.update(workspaceId, block.id, {
245
+ status: 'pr_ready',
246
+ progress: 1,
247
+ });
248
+ }
249
+ return;
250
+ }
251
+ // No merger in this pipeline: complete but unmerged — ask a human to confirm.
252
+ await this.blockRepository.update(workspaceId, block.id, { status: 'pr_ready', progress: 1 });
253
+ await this.raisePipelineComplete(workspaceId, instance, block);
254
+ }
255
+ async raisePipelineComplete(workspaceId, instance, block) {
256
+ if (!this.notificationService)
257
+ return;
258
+ await this.notificationService.raise(workspaceId, {
259
+ type: 'pipeline_complete',
260
+ blockId: block.id,
261
+ executionId: instance.id,
262
+ title: `Confirm "${block.title}" is complete`,
263
+ body: `The "${instance.pipelineName}" pipeline finished and opened a PR, but it has no ` +
264
+ `merger step. Review the work and confirm it as complete (this merges the PR).`,
265
+ payload: {
266
+ ...(block.pullRequest?.url ? { prUrl: block.pullRequest.url } : {}),
267
+ pipelineName: instance.pipelineName,
268
+ },
269
+ });
270
+ }
271
+ /**
272
+ * Record a terminal failure on a run: reclaim its container, mark it `failed` with the
273
+ * richest failure record (first write wins), drop the block to `blocked` with the
274
+ * progress it reached, and emit. The single funnel for every failure kind.
275
+ */
276
+ async failRun(workspaceId, executionId, message, kind = 'agent', detail = null) {
277
+ const instance = await this.executionRepository.get(workspaceId, executionId);
278
+ if (!instance)
279
+ return;
280
+ // Reclaim the per-run container on the failure path too: a failed run otherwise
281
+ // leaves its container to idle out sleepAfter. This is the single funnel for
282
+ // every failure kind (job_failed from the driver, the spend/decision timeouts,
283
+ // and the user-facing stopRun, which already reclaimed — the call is idempotent).
284
+ await this.stopRunContainer(workspaceId, instance);
285
+ // The FIRST recorded failure wins: a run already in a terminal `failed` state keeps
286
+ // its existing (richest) failure rather than being overwritten. An inline gate that
287
+ // knows the precise kind/detail returns a `job_failed` result the driver funnels here,
288
+ // so there should only ever be one write — but this guards against a future path that
289
+ // both records a failure and returns `job_failed`, which would otherwise clobber the
290
+ // good record with a generic one (the companion-rejected regression).
291
+ if (instance.status === 'failed')
292
+ return;
293
+ const failure = {
294
+ kind,
295
+ message,
296
+ detail,
297
+ hint: EXECUTION_FAILURE_HINTS[kind] ?? null,
298
+ occurredAt: this.clock.now(),
299
+ lastSubtasks: instance.steps[instance.currentStep]?.subtasks ?? null,
300
+ };
301
+ await this.executionRepository.markFailed(workspaceId, executionId, failure);
302
+ // Progress reflects how far the pipeline got before failing.
303
+ const done = instance.steps.filter((s) => s.state === 'done').length;
304
+ const progress = instance.steps.length > 0 ? done / instance.steps.length : 0;
305
+ await this.blockRepository.update(workspaceId, instance.blockId, {
306
+ status: 'blocked',
307
+ progress,
308
+ });
309
+ const failed = await this.executionRepository.get(workspaceId, executionId);
310
+ if (failed)
311
+ await this.emitInstance(workspaceId, failed);
312
+ }
313
+ /** Reclaim the per-run container (per-job backends cancel the parked job; run-container
314
+ * backends use the run id). Best-effort: a vanished container is nothing to reclaim. */
315
+ async stopRunContainer(workspaceId, instance) {
316
+ const executor = this.agentExecutor;
317
+ if (!isAsyncAgentExecutor(executor) || !executor.stopJob)
318
+ return;
319
+ // The in-flight step's job id (when a job is parked), so a per-job backend can
320
+ // cancel exactly it; the run-container backends ignore it and use the run id.
321
+ const jobId = instance.steps[instance.currentStep]?.jobId ?? instance.id;
322
+ try {
323
+ await executor.stopJob({ jobId, runId: instance.id, workspaceId });
324
+ }
325
+ catch {
326
+ // The container may already be gone (eviction/completion) — nothing to reclaim.
327
+ }
328
+ }
329
+ /** Raise the iteration-cap `decision_required` card when a review loop parks at its cap. */
330
+ async raiseDecisionRequired(workspaceId, instance) {
331
+ if (!this.notificationService)
332
+ return;
333
+ const block = await this.blockRepository.get(workspaceId, instance.blockId);
334
+ if (!block)
335
+ return;
336
+ await this.notificationService.raise(workspaceId, {
337
+ type: 'decision_required',
338
+ blockId: block.id,
339
+ executionId: instance.id,
340
+ title: `"${block.title}" ran out of automatic iterations and needs your decision`,
341
+ body: 'An automatic review loop reached its iteration cap without converging. Open the ' +
342
+ 'task to choose: one more round, proceed with the current result, or stop and reset.',
343
+ payload: { pipelineName: instance.pipelineName },
344
+ });
345
+ }
346
+ /**
347
+ * Ensure an open notification exists for a run that has just parked waiting for a human
348
+ * (an agent-raised decision, an approval gate, or an iterative review gate). Without
349
+ * the old decision timeout the run waits indefinitely, so the inbox card — which the
350
+ * periodic sweep escalates yellow → red — is the only signal a human is needed.
351
+ *
352
+ * Non-clobbering: if ANY open notification is already on the block (a more specific
353
+ * `merge_review`, iteration-cap `decision_required`, etc.), it is left untouched and we
354
+ * raise nothing — so the richer message wins. Best-effort: no notification service
355
+ * (tests) or a missing block is a no-op.
356
+ */
357
+ async ensureWaitingNotification(workspaceId, instance) {
358
+ const svc = this.notificationService;
359
+ if (!svc)
360
+ return;
361
+ const open = await svc.listOpen(workspaceId);
362
+ if (open.some((n) => n.blockId === instance.blockId))
363
+ return;
364
+ const block = await this.blockRepository.get(workspaceId, instance.blockId);
365
+ if (!block)
366
+ return;
367
+ await svc.raise(workspaceId, {
368
+ type: 'decision_required',
369
+ blockId: block.id,
370
+ executionId: instance.id,
371
+ title: `"${block.title}" is waiting for your input`,
372
+ body: 'A pipeline step is parked awaiting a human decision. Open the task to respond.',
373
+ payload: { pipelineName: instance.pipelineName },
374
+ });
375
+ }
376
+ /**
377
+ * Clear the auto-raised "waiting for a human decision" card once a run advances past
378
+ * the decision it was parked on (so the escalation sweep can't flip a settled decision
379
+ * red). Scoped to the `decision_required` type, so the human-actionable cards a stopped
380
+ * run leaves behind are untouched. Best-effort: no notification service (tests) is a no-op.
381
+ */
382
+ async clearWaitingNotification(workspaceId, instance) {
383
+ const svc = this.notificationService;
384
+ if (!svc)
385
+ return;
386
+ await svc.clearWaitingDecision(workspaceId, instance.blockId);
387
+ }
388
+ }
389
+ //# sourceMappingURL=RunStateMachine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RunStateMachine.js","sourceRoot":"","sources":["../../../src/modules/execution/RunStateMachine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ import type { Clock, ExecutionInstance, PipelineStep } from '@cat-factory/kernel';
2
+ /**
3
+ * The pure, synchronous step/cursor mutators of the execution engine — the dependency-free
4
+ * inner layer of the run state-machine spine. Every method operates on a passed
5
+ * {@link PipelineStep} / {@link ExecutionInstance} and mutates it in place; the only
6
+ * collaborator is the {@link Clock} the timing stamps come from. Lifted verbatim out of
7
+ * `ExecutionService` so the engine AND every gate controller share ONE definition of "what
8
+ * does it mean to start / finish / park / reset a step" instead of each receiving the
9
+ * mutators as a loose callback bag.
10
+ *
11
+ * Deliberately holds NO repositories, event publisher or runner — those async,
12
+ * instance-persisting concerns live in {@link RunStateMachine}, which composes this. Keeping
13
+ * the pure mutators separate is what lets a controller depend on the timing rules without
14
+ * pulling in the whole persistence/emission surface.
15
+ */
16
+ export declare class StepGraph {
17
+ private readonly clock;
18
+ constructor(clock: Clock);
19
+ /** Transition a step into `working`, stamping its start time once, and resume its clock. */
20
+ startStep(step: PipelineStep): void;
21
+ /**
22
+ * Transition a step into `done`, stamping its finish time once. Set-once so the
23
+ * approval-gate flow (which re-asserts `done` after a human approves, long after
24
+ * the agent actually finished) keeps the agent's true completion time, and so a
25
+ * replay doesn't move it. With {@link startStep}'s `startedAt` this yields the
26
+ * step's execution duration. A step finished directly out of a parked approval
27
+ * stopped *working* when it parked, so its duration is billed to the pause instant
28
+ * ({@link pauseStepForInput}), not the (later) moment the human decided.
29
+ */
30
+ finishStep(step: PipelineStep): void;
31
+ /**
32
+ * Park a step on a human decision and freeze its duration clock. Records when the
33
+ * step stopped working (`pausedAt`) so elapsed time no longer accrues while it waits
34
+ * for input — the symmetric counterpart of the terminal freeze on `finishedAt`.
35
+ * Set-once (a Workflows replay re-parking keeps the original instant); cleared when
36
+ * the step resumes ({@link startStep}) or finishes ({@link finishStep}).
37
+ */
38
+ pauseStepForInput(step: PipelineStep): void;
39
+ /**
40
+ * Reset a step so the durable driver re-runs it from scratch: clear its live container
41
+ * job handle (so it dispatches FRESH work rather than re-attaching to a stale/evicted
42
+ * job), timings, approval, subtasks and prior output.
43
+ */
44
+ resetStepForRerun(step: PipelineStep): void;
45
+ /**
46
+ * Loop a producer step back for rework and re-run every step from it up to and
47
+ * including the companion at `companionIndex`: each one is reset (crucially clearing
48
+ * stale container job handles so an intermediate container step re-dispatches fresh
49
+ * work instead of re-attaching to its evicted job), the producer is handed the
50
+ * `rework` feedback + started, and the instance cursor is moved back to the producer.
51
+ * Shared by the automatic companion loop and the human "request changes" path.
52
+ */
53
+ rerunProducerThrough(instance: ExecutionInstance, producerIndex: number, companionIndex: number, rework: NonNullable<PipelineStep['rework']>): void;
54
+ /**
55
+ * The index of the nearest preceding step a companion grades (one of its target
56
+ * producer kinds), or -1 when none precedes it. The single producer-search used by the
57
+ * automatic companion loop, the human "request changes" redirect, and the iteration-cap
58
+ * extra-round resolution.
59
+ */
60
+ companionProducerIndex(instance: ExecutionInstance, companionIndex: number): number;
61
+ /**
62
+ * Loop a companion's producer back for one more automatic rework cycle: charge one
63
+ * attempt against the budget, then re-run the producer (and any intermediate steps) up
64
+ * to and including the companion so it re-grades. Shared by the automatic
65
+ * below-threshold loop and the human-granted extra round, so both consume the budget
66
+ * identically.
67
+ */
68
+ loopCompanionProducer(instance: ExecutionInstance, companionIndex: number, rework: NonNullable<PipelineStep['rework']>): void;
69
+ }
70
+ //# sourceMappingURL=StepGraph.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StepGraph.d.ts","sourceRoot":"","sources":["../../../src/modules/execution/StepGraph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAGjF;;;;;;;;;;;;;GAaG;AACH,qBAAa,SAAS;IACR,OAAO,CAAC,QAAQ,CAAC,KAAK;IAAlC,YAA6B,KAAK,EAAE,KAAK,EAAI;IAE7C,4FAA4F;IAC5F,SAAS,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAMlC;IAED;;;;;;;;OAQG;IACH,UAAU,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAInC;IAED;;;;;;OAMG;IACH,iBAAiB,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAG1C;IAED;;;;OAIG;IACH,iBAAiB,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAc1C;IAED;;;;;;;OAOG;IACH,oBAAoB,CAClB,QAAQ,EAAE,iBAAiB,EAC3B,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,WAAW,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,GAC1C,IAAI,CAQN;IAED;;;;;OAKG;IACH,sBAAsB,CAAC,QAAQ,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,GAAG,MAAM,CAMlF;IAED;;;;;;OAMG;IACH,qBAAqB,CACnB,QAAQ,EAAE,iBAAiB,EAC3B,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,WAAW,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,GAC1C,IAAI,CAMN;CACF"}
@@ -0,0 +1,124 @@
1
+ import { companionTargets } from '@cat-factory/agents';
2
+ /**
3
+ * The pure, synchronous step/cursor mutators of the execution engine — the dependency-free
4
+ * inner layer of the run state-machine spine. Every method operates on a passed
5
+ * {@link PipelineStep} / {@link ExecutionInstance} and mutates it in place; the only
6
+ * collaborator is the {@link Clock} the timing stamps come from. Lifted verbatim out of
7
+ * `ExecutionService` so the engine AND every gate controller share ONE definition of "what
8
+ * does it mean to start / finish / park / reset a step" instead of each receiving the
9
+ * mutators as a loose callback bag.
10
+ *
11
+ * Deliberately holds NO repositories, event publisher or runner — those async,
12
+ * instance-persisting concerns live in {@link RunStateMachine}, which composes this. Keeping
13
+ * the pure mutators separate is what lets a controller depend on the timing rules without
14
+ * pulling in the whole persistence/emission surface.
15
+ */
16
+ export class StepGraph {
17
+ clock;
18
+ constructor(clock) {
19
+ this.clock = clock;
20
+ }
21
+ /** Transition a step into `working`, stamping its start time once, and resume its clock. */
22
+ startStep(step) {
23
+ step.state = 'working';
24
+ if (step.startedAt == null)
25
+ step.startedAt = this.clock.now();
26
+ // (Re)entering `working` means the step is no longer parked on a human: resume
27
+ // its duration clock (see {@link pauseStepForInput}).
28
+ step.pausedAt = null;
29
+ }
30
+ /**
31
+ * Transition a step into `done`, stamping its finish time once. Set-once so the
32
+ * approval-gate flow (which re-asserts `done` after a human approves, long after
33
+ * the agent actually finished) keeps the agent's true completion time, and so a
34
+ * replay doesn't move it. With {@link startStep}'s `startedAt` this yields the
35
+ * step's execution duration. A step finished directly out of a parked approval
36
+ * stopped *working* when it parked, so its duration is billed to the pause instant
37
+ * ({@link pauseStepForInput}), not the (later) moment the human decided.
38
+ */
39
+ finishStep(step) {
40
+ step.state = 'done';
41
+ if (step.finishedAt == null)
42
+ step.finishedAt = step.pausedAt ?? this.clock.now();
43
+ step.pausedAt = null;
44
+ }
45
+ /**
46
+ * Park a step on a human decision and freeze its duration clock. Records when the
47
+ * step stopped working (`pausedAt`) so elapsed time no longer accrues while it waits
48
+ * for input — the symmetric counterpart of the terminal freeze on `finishedAt`.
49
+ * Set-once (a Workflows replay re-parking keeps the original instant); cleared when
50
+ * the step resumes ({@link startStep}) or finishes ({@link finishStep}).
51
+ */
52
+ pauseStepForInput(step) {
53
+ step.state = 'waiting_decision';
54
+ if (step.pausedAt == null)
55
+ step.pausedAt = this.clock.now();
56
+ }
57
+ /**
58
+ * Reset a step so the durable driver re-runs it from scratch: clear its live container
59
+ * job handle (so it dispatches FRESH work rather than re-attaching to a stale/evicted
60
+ * job), timings, approval, subtasks and prior output.
61
+ */
62
+ resetStepForRerun(step) {
63
+ step.state = 'pending';
64
+ step.startedAt = null;
65
+ step.finishedAt = null;
66
+ step.pausedAt = null;
67
+ step.jobId = undefined;
68
+ step.approval = null;
69
+ step.subtasks = undefined;
70
+ step.progress = 0;
71
+ step.output = undefined;
72
+ // Drop the prior run's structured output too, so a re-run that produces no `custom`
73
+ // doesn't leave stale JSON for the `generic-structured` result view to render.
74
+ step.custom = undefined;
75
+ step.rework = undefined;
76
+ }
77
+ /**
78
+ * Loop a producer step back for rework and re-run every step from it up to and
79
+ * including the companion at `companionIndex`: each one is reset (crucially clearing
80
+ * stale container job handles so an intermediate container step re-dispatches fresh
81
+ * work instead of re-attaching to its evicted job), the producer is handed the
82
+ * `rework` feedback + started, and the instance cursor is moved back to the producer.
83
+ * Shared by the automatic companion loop and the human "request changes" path.
84
+ */
85
+ rerunProducerThrough(instance, producerIndex, companionIndex, rework) {
86
+ for (let i = producerIndex; i <= companionIndex; i++) {
87
+ this.resetStepForRerun(instance.steps[i]);
88
+ }
89
+ const producer = instance.steps[producerIndex];
90
+ producer.rework = rework;
91
+ this.startStep(producer);
92
+ instance.currentStep = producerIndex;
93
+ }
94
+ /**
95
+ * The index of the nearest preceding step a companion grades (one of its target
96
+ * producer kinds), or -1 when none precedes it. The single producer-search used by the
97
+ * automatic companion loop, the human "request changes" redirect, and the iteration-cap
98
+ * extra-round resolution.
99
+ */
100
+ companionProducerIndex(instance, companionIndex) {
101
+ const targets = companionTargets(instance.steps[companionIndex].agentKind);
102
+ for (let i = companionIndex - 1; i >= 0; i--) {
103
+ if (targets.includes(instance.steps[i].agentKind))
104
+ return i;
105
+ }
106
+ return -1;
107
+ }
108
+ /**
109
+ * Loop a companion's producer back for one more automatic rework cycle: charge one
110
+ * attempt against the budget, then re-run the producer (and any intermediate steps) up
111
+ * to and including the companion so it re-grades. Shared by the automatic
112
+ * below-threshold loop and the human-granted extra round, so both consume the budget
113
+ * identically.
114
+ */
115
+ loopCompanionProducer(instance, companionIndex, rework) {
116
+ const companionStep = instance.steps[companionIndex];
117
+ const producerIndex = this.companionProducerIndex(instance, companionIndex);
118
+ companionStep.companion.attempts += 1;
119
+ this.rerunProducerThrough(instance, producerIndex, companionIndex, rework);
120
+ if (instance.status === 'blocked')
121
+ instance.status = 'running';
122
+ }
123
+ }
124
+ //# sourceMappingURL=StepGraph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StepGraph.js","sourceRoot":"","sources":["../../../src/modules/execution/StepGraph.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ import type { AgentExecutor, AgentRunResult, Block, BlockRepository, ExecutionIn
2
2
  import type { NotificationService } from '../notifications/NotificationService.js';
3
3
  import type { AdvanceResult } from './advance.js';
4
4
  import type { AgentContextBuilder } from './AgentContextBuilder.js';
5
+ import type { RunStateMachine } from './RunStateMachine.js';
5
6
  /** The engine collaborators the Tester gate drives (kept on the engine, injected here). */
6
7
  export interface TesterControllerDeps {
7
8
  blockRepository: BlockRepository;
@@ -12,10 +13,8 @@ export interface TesterControllerDeps {
12
13
  resolveMergePreset: (workspaceId: string, block: Block) => Promise<{
13
14
  ciMaxAttempts: number;
14
15
  }>;
15
- /** Reclaim the run's finished container before dispatching the next job. */
16
- stopRunContainer: (workspaceId: string, instance: ExecutionInstance) => Promise<void>;
17
- persistInstance: (workspaceId: string, instance: ExecutionInstance) => Promise<void>;
18
- emitInstance: (workspaceId: string, instance: ExecutionInstance) => Promise<void>;
16
+ /** The async instance/block spine (container reclaim, instance persist + emit). */
17
+ stateMachine: RunStateMachine;
19
18
  }
20
19
  /**
21
20
  * Drives the Tester gate's fix loop: apply a Tester report to its step (greenlight →
@@ -1 +1 @@
1
- {"version":3,"file":"TesterController.d.ts","sourceRoot":"","sources":["../../../src/modules/execution/TesterController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EAEb,cAAc,EACd,KAAK,EACL,eAAe,EACf,iBAAiB,EACjB,YAAY,EACb,MAAM,qBAAqB,CAAA;AAI5B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAA;AAClF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AA4CnE,2FAA2F;AAC3F,MAAM,WAAW,oBAAoB;IACnC,eAAe,EAAE,eAAe,CAAA;IAChC,mBAAmB,CAAC,EAAE,mBAAmB,CAAA;IACzC,aAAa,EAAE,aAAa,CAAA;IAC5B,cAAc,EAAE,mBAAmB,CAAA;IACnC,0EAA0E;IAC1E,kBAAkB,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC7F,4EAA4E;IAC5E,gBAAgB,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACrF,eAAe,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACpF,YAAY,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAClF;AAED;;;;;;;GAOG;AACH,qBAAa,gBAAgB;IACf,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,EAAE,oBAAoB,EAAI;IAE3D;;;;;;OAMG;IACG,mBAAmB,CACvB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CA+D/B;IAED;;;OAGG;IACG,cAAc,CAClB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,KAAK,GACX,OAAO,CAAC,aAAa,CAAC,CAsBxB;IAED;;;;;OAKG;YACW,UAAU;IAkBxB,wEAAwE;YAC1D,eAAe;IAuB7B;;;;;OAKG;YACW,aAAa;CA0D5B"}
1
+ {"version":3,"file":"TesterController.d.ts","sourceRoot":"","sources":["../../../src/modules/execution/TesterController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EAEb,cAAc,EACd,KAAK,EACL,eAAe,EACf,iBAAiB,EACjB,YAAY,EACb,MAAM,qBAAqB,CAAA;AAI5B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAA;AAClF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AA4C3D,2FAA2F;AAC3F,MAAM,WAAW,oBAAoB;IACnC,eAAe,EAAE,eAAe,CAAA;IAChC,mBAAmB,CAAC,EAAE,mBAAmB,CAAA;IACzC,aAAa,EAAE,aAAa,CAAA;IAC5B,cAAc,EAAE,mBAAmB,CAAA;IACnC,0EAA0E;IAC1E,kBAAkB,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC7F,mFAAmF;IACnF,YAAY,EAAE,eAAe,CAAA;CAC9B;AAED;;;;;;;GAOG;AACH,qBAAa,gBAAgB;IACf,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,EAAE,oBAAoB,EAAI;IAE3D;;;;;;OAMG;IACG,mBAAmB,CACvB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CA+D/B;IAED;;;OAGG;IACG,cAAc,CAClB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,KAAK,GACX,OAAO,CAAC,aAAa,CAAC,CAsBxB;IAED;;;;;OAKG;YACW,UAAU;IAkBxB,wEAAwE;YAC1D,eAAe;IAuB7B;;;;;OAKG;YACW,aAAa;CA0D5B"}