@cat-factory/orchestration 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/LICENSE +21 -0
  2. package/dist/container.d.ts +460 -0
  3. package/dist/container.d.ts.map +1 -0
  4. package/dist/container.js +657 -0
  5. package/dist/container.js.map +1 -0
  6. package/dist/index.d.ts +29 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +31 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/modules/board/BoardService.d.ts +125 -0
  11. package/dist/modules/board/BoardService.d.ts.map +1 -0
  12. package/dist/modules/board/BoardService.js +496 -0
  13. package/dist/modules/board/BoardService.js.map +1 -0
  14. package/dist/modules/board/board.logic.d.ts +17 -0
  15. package/dist/modules/board/board.logic.d.ts.map +1 -0
  16. package/dist/modules/board/board.logic.js +51 -0
  17. package/dist/modules/board/board.logic.js.map +1 -0
  18. package/dist/modules/boardScan/BoardScanService.d.ts +35 -0
  19. package/dist/modules/boardScan/BoardScanService.d.ts.map +1 -0
  20. package/dist/modules/boardScan/BoardScanService.js +91 -0
  21. package/dist/modules/boardScan/BoardScanService.js.map +1 -0
  22. package/dist/modules/boardScan/board-scan.logic.d.ts +10 -0
  23. package/dist/modules/boardScan/board-scan.logic.d.ts.map +1 -0
  24. package/dist/modules/boardScan/board-scan.logic.js +26 -0
  25. package/dist/modules/boardScan/board-scan.logic.js.map +1 -0
  26. package/dist/modules/bootstrap/BootstrapService.d.ts +114 -0
  27. package/dist/modules/bootstrap/BootstrapService.d.ts.map +1 -0
  28. package/dist/modules/bootstrap/BootstrapService.js +516 -0
  29. package/dist/modules/bootstrap/BootstrapService.js.map +1 -0
  30. package/dist/modules/clarity/ClarityReviewService.d.ts +48 -0
  31. package/dist/modules/clarity/ClarityReviewService.d.ts.map +1 -0
  32. package/dist/modules/clarity/ClarityReviewService.js +63 -0
  33. package/dist/modules/clarity/ClarityReviewService.js.map +1 -0
  34. package/dist/modules/clarity/clarity.logic.d.ts +36 -0
  35. package/dist/modules/clarity/clarity.logic.d.ts.map +1 -0
  36. package/dist/modules/clarity/clarity.logic.js +98 -0
  37. package/dist/modules/clarity/clarity.logic.js.map +1 -0
  38. package/dist/modules/estimation/estimate.logic.d.ts +11 -0
  39. package/dist/modules/estimation/estimate.logic.d.ts.map +1 -0
  40. package/dist/modules/estimation/estimate.logic.js +37 -0
  41. package/dist/modules/estimation/estimate.logic.js.map +1 -0
  42. package/dist/modules/execution/AgentContextBuilder.d.ts +114 -0
  43. package/dist/modules/execution/AgentContextBuilder.d.ts.map +1 -0
  44. package/dist/modules/execution/AgentContextBuilder.js +316 -0
  45. package/dist/modules/execution/AgentContextBuilder.js.map +1 -0
  46. package/dist/modules/execution/CompanionController.d.ts +60 -0
  47. package/dist/modules/execution/CompanionController.d.ts.map +1 -0
  48. package/dist/modules/execution/CompanionController.js +216 -0
  49. package/dist/modules/execution/CompanionController.js.map +1 -0
  50. package/dist/modules/execution/ExecutionService.d.ts +874 -0
  51. package/dist/modules/execution/ExecutionService.d.ts.map +1 -0
  52. package/dist/modules/execution/ExecutionService.js +2921 -0
  53. package/dist/modules/execution/ExecutionService.js.map +1 -0
  54. package/dist/modules/execution/MergeResolver.d.ts +34 -0
  55. package/dist/modules/execution/MergeResolver.d.ts.map +1 -0
  56. package/dist/modules/execution/MergeResolver.js +81 -0
  57. package/dist/modules/execution/MergeResolver.js.map +1 -0
  58. package/dist/modules/execution/ReviewGateController.d.ts +163 -0
  59. package/dist/modules/execution/ReviewGateController.d.ts.map +1 -0
  60. package/dist/modules/execution/ReviewGateController.js +251 -0
  61. package/dist/modules/execution/ReviewGateController.js.map +1 -0
  62. package/dist/modules/execution/TesterController.d.ts +61 -0
  63. package/dist/modules/execution/TesterController.d.ts.map +1 -0
  64. package/dist/modules/execution/TesterController.js +215 -0
  65. package/dist/modules/execution/TesterController.js.map +1 -0
  66. package/dist/modules/execution/advance.d.ts +84 -0
  67. package/dist/modules/execution/advance.d.ts.map +1 -0
  68. package/dist/modules/execution/advance.js +2 -0
  69. package/dist/modules/execution/advance.js.map +1 -0
  70. package/dist/modules/execution/artifact-review.logic.d.ts +25 -0
  71. package/dist/modules/execution/artifact-review.logic.d.ts.map +1 -0
  72. package/dist/modules/execution/artifact-review.logic.js +39 -0
  73. package/dist/modules/execution/artifact-review.logic.js.map +1 -0
  74. package/dist/modules/execution/ci.logic.d.ts +101 -0
  75. package/dist/modules/execution/ci.logic.d.ts.map +1 -0
  76. package/dist/modules/execution/ci.logic.js +117 -0
  77. package/dist/modules/execution/ci.logic.js.map +1 -0
  78. package/dist/modules/execution/drive.d.ts +47 -0
  79. package/dist/modules/execution/drive.d.ts.map +1 -0
  80. package/dist/modules/execution/drive.js +112 -0
  81. package/dist/modules/execution/drive.js.map +1 -0
  82. package/dist/modules/execution/gates.d.ts +97 -0
  83. package/dist/modules/execution/gates.d.ts.map +1 -0
  84. package/dist/modules/execution/gates.js +2 -0
  85. package/dist/modules/execution/gates.js.map +1 -0
  86. package/dist/modules/execution/individualVendors.logic.d.ts +22 -0
  87. package/dist/modules/execution/individualVendors.logic.d.ts.map +1 -0
  88. package/dist/modules/execution/individualVendors.logic.js +33 -0
  89. package/dist/modules/execution/individualVendors.logic.js.map +1 -0
  90. package/dist/modules/execution/job.logic.d.ts +52 -0
  91. package/dist/modules/execution/job.logic.d.ts.map +1 -0
  92. package/dist/modules/execution/job.logic.js +56 -0
  93. package/dist/modules/execution/job.logic.js.map +1 -0
  94. package/dist/modules/execution/release.logic.d.ts +43 -0
  95. package/dist/modules/execution/release.logic.d.ts.map +1 -0
  96. package/dist/modules/execution/release.logic.js +49 -0
  97. package/dist/modules/execution/release.logic.js.map +1 -0
  98. package/dist/modules/execution/retry.logic.d.ts +40 -0
  99. package/dist/modules/execution/retry.logic.d.ts.map +1 -0
  100. package/dist/modules/execution/retry.logic.js +83 -0
  101. package/dist/modules/execution/retry.logic.js.map +1 -0
  102. package/dist/modules/execution/stepGating.logic.d.ts +15 -0
  103. package/dist/modules/execution/stepGating.logic.d.ts.map +1 -0
  104. package/dist/modules/execution/stepGating.logic.js +29 -0
  105. package/dist/modules/execution/stepGating.logic.js.map +1 -0
  106. package/dist/modules/execution/stepResolvers.d.ts +41 -0
  107. package/dist/modules/execution/stepResolvers.d.ts.map +1 -0
  108. package/dist/modules/execution/stepResolvers.js +2 -0
  109. package/dist/modules/execution/stepResolvers.js.map +1 -0
  110. package/dist/modules/execution/tester-infra.logic.d.ts +42 -0
  111. package/dist/modules/execution/tester-infra.logic.d.ts.map +1 -0
  112. package/dist/modules/execution/tester-infra.logic.js +46 -0
  113. package/dist/modules/execution/tester-infra.logic.js.map +1 -0
  114. package/dist/modules/merge/MergePresetService.d.ts +32 -0
  115. package/dist/modules/merge/MergePresetService.d.ts.map +1 -0
  116. package/dist/modules/merge/MergePresetService.js +109 -0
  117. package/dist/modules/merge/MergePresetService.js.map +1 -0
  118. package/dist/modules/modelDefaults/ModelDefaultsService.d.ts +22 -0
  119. package/dist/modules/modelDefaults/ModelDefaultsService.d.ts.map +1 -0
  120. package/dist/modules/modelDefaults/ModelDefaultsService.js +28 -0
  121. package/dist/modules/modelDefaults/ModelDefaultsService.js.map +1 -0
  122. package/dist/modules/notifications/NotificationService.d.ts +74 -0
  123. package/dist/modules/notifications/NotificationService.d.ts.map +1 -0
  124. package/dist/modules/notifications/NotificationService.js +131 -0
  125. package/dist/modules/notifications/NotificationService.js.map +1 -0
  126. package/dist/modules/observability/LlmObservabilityService.d.ts +121 -0
  127. package/dist/modules/observability/LlmObservabilityService.d.ts.map +1 -0
  128. package/dist/modules/observability/LlmObservabilityService.js +140 -0
  129. package/dist/modules/observability/LlmObservabilityService.js.map +1 -0
  130. package/dist/modules/observability/observability.logic.d.ts +57 -0
  131. package/dist/modules/observability/observability.logic.d.ts.map +1 -0
  132. package/dist/modules/observability/observability.logic.js +186 -0
  133. package/dist/modules/observability/observability.logic.js.map +1 -0
  134. package/dist/modules/pipelines/PipelineService.d.ts +54 -0
  135. package/dist/modules/pipelines/PipelineService.d.ts.map +1 -0
  136. package/dist/modules/pipelines/PipelineService.js +226 -0
  137. package/dist/modules/pipelines/PipelineService.js.map +1 -0
  138. package/dist/modules/pipelines/pipelineShape.d.ts +53 -0
  139. package/dist/modules/pipelines/pipelineShape.d.ts.map +1 -0
  140. package/dist/modules/pipelines/pipelineShape.js +74 -0
  141. package/dist/modules/pipelines/pipelineShape.js.map +1 -0
  142. package/dist/modules/recurring/RecurringPipelineService.d.ts +76 -0
  143. package/dist/modules/recurring/RecurringPipelineService.d.ts.map +1 -0
  144. package/dist/modules/recurring/RecurringPipelineService.js +295 -0
  145. package/dist/modules/recurring/RecurringPipelineService.js.map +1 -0
  146. package/dist/modules/recurring/TrackerSettingsService.d.ts +16 -0
  147. package/dist/modules/recurring/TrackerSettingsService.d.ts.map +1 -0
  148. package/dist/modules/recurring/TrackerSettingsService.js +30 -0
  149. package/dist/modules/recurring/TrackerSettingsService.js.map +1 -0
  150. package/dist/modules/recurring/schedule.logic.d.ts +14 -0
  151. package/dist/modules/recurring/schedule.logic.d.ts.map +1 -0
  152. package/dist/modules/recurring/schedule.logic.js +85 -0
  153. package/dist/modules/recurring/schedule.logic.js.map +1 -0
  154. package/dist/modules/releaseHealth/ReleaseHealthService.d.ts +38 -0
  155. package/dist/modules/releaseHealth/ReleaseHealthService.d.ts.map +1 -0
  156. package/dist/modules/releaseHealth/ReleaseHealthService.js +96 -0
  157. package/dist/modules/releaseHealth/ReleaseHealthService.js.map +1 -0
  158. package/dist/modules/requirements/RequirementReviewService.d.ts +48 -0
  159. package/dist/modules/requirements/RequirementReviewService.d.ts.map +1 -0
  160. package/dist/modules/requirements/RequirementReviewService.js +83 -0
  161. package/dist/modules/requirements/RequirementReviewService.js.map +1 -0
  162. package/dist/modules/requirements/requirements.logic.d.ts +93 -0
  163. package/dist/modules/requirements/requirements.logic.d.ts.map +1 -0
  164. package/dist/modules/requirements/requirements.logic.js +203 -0
  165. package/dist/modules/requirements/requirements.logic.js.map +1 -0
  166. package/dist/modules/review/IterativeReviewService.d.ts +175 -0
  167. package/dist/modules/review/IterativeReviewService.d.ts.map +1 -0
  168. package/dist/modules/review/IterativeReviewService.js +327 -0
  169. package/dist/modules/review/IterativeReviewService.js.map +1 -0
  170. package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsService.d.ts +20 -0
  171. package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsService.d.ts.map +1 -0
  172. package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsService.js +26 -0
  173. package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsService.js.map +1 -0
  174. package/dist/modules/services/ServiceMountService.d.ts +48 -0
  175. package/dist/modules/services/ServiceMountService.d.ts.map +1 -0
  176. package/dist/modules/services/ServiceMountService.js +90 -0
  177. package/dist/modules/services/ServiceMountService.js.map +1 -0
  178. package/dist/modules/settings/WorkspaceSettingsService.d.ts +22 -0
  179. package/dist/modules/settings/WorkspaceSettingsService.d.ts.map +1 -0
  180. package/dist/modules/settings/WorkspaceSettingsService.js +50 -0
  181. package/dist/modules/settings/WorkspaceSettingsService.js.map +1 -0
  182. package/package.json +41 -0
@@ -0,0 +1,84 @@
1
+ import type { AgentFailureKind } from '@cat-factory/kernel';
2
+ export type AdvanceResult =
3
+ /** The step completed; the run is still running and has more steps. */
4
+ {
5
+ kind: 'continue';
6
+ }
7
+ /** The step raised a decision; the run is parked until it is resolved. */
8
+ | {
9
+ kind: 'awaiting_decision';
10
+ decisionId: string;
11
+ }
12
+ /**
13
+ * The step dispatched an asynchronous agent job (a container run). The run is
14
+ * parked: the durable driver polls {@link ExecutionService.pollAgentJob} between
15
+ * sleeps until the job finishes, then records its result and continues.
16
+ */
17
+ | {
18
+ kind: 'awaiting_job';
19
+ jobId: string;
20
+ stepIndex: number;
21
+ }
22
+ /**
23
+ * A polling **gate** step (`ci` / `conflicts`) is gating the PR on its precheck.
24
+ * The run is parked: the durable driver sleeps, then polls
25
+ * {@link ExecutionService.pollGate} to re-run the precheck (which gate is resolved
26
+ * from the current step's `agentKind`). Polling stops the moment `pollGate` returns
27
+ * anything else — a passing precheck yields `continue`, a dispatched helper agent
28
+ * (ci-fixer / conflict-resolver) yields `awaiting_job`, exhaustion fails the run.
29
+ */
30
+ | {
31
+ kind: 'awaiting_gate';
32
+ stepIndex: number;
33
+ }
34
+ /**
35
+ * A step finished in a terminal failure; the driver records it via the single
36
+ * `failRun` funnel and stops. `error` is the human-readable message. An inline
37
+ * gate that already knows the precise classification sets `failureKind` (e.g. an
38
+ * unparseable companion verdict → `'companion_rejected'`, a Tester gate that
39
+ * exhausted its fixer budget → `'agent'`) and may attach extended `detail` (e.g.
40
+ * the companion's raw reply); the driver records those instead of the generic
41
+ * `'job_failed'` container-failure framing. Defaults: `failureKind` →
42
+ * `'job_failed'`, `detail` → none. Inline gates MUST NOT call `failRun`
43
+ * themselves — returning this is the single path so the driver can't double-write
44
+ * and clobber the rich record.
45
+ */
46
+ | {
47
+ kind: 'job_failed';
48
+ error: string;
49
+ failureKind?: AgentFailureKind;
50
+ detail?: string;
51
+ }
52
+ /**
53
+ * A polled async job's container was evicted/crashed and the single automatic
54
+ * recovery (a fresh-container re-dispatch of the same step) has been spent, so the
55
+ * eviction is treated as deterministic. The driver fails the run as `evicted`.
56
+ * (A first eviction is recovered silently inside {@link ExecutionService.pollAgentJob}
57
+ * by re-dispatching and returning `continue`, so it never reaches the driver.)
58
+ */
59
+ | {
60
+ kind: 'job_evicted';
61
+ error: string;
62
+ }
63
+ /** The final step completed; the run is finished. */
64
+ | {
65
+ kind: 'done';
66
+ }
67
+ /** The spend budget is exhausted; the run is paused until it frees up. */
68
+ | {
69
+ kind: 'paused';
70
+ }
71
+ /** Nothing to do — the run is absent or not running (replay/idempotent). */
72
+ | {
73
+ kind: 'noop';
74
+ };
75
+ /** Options controlling how a single advance behaves. */
76
+ export interface AdvanceOptions {
77
+ /**
78
+ * When true, an agent failure is rethrown instead of being swallowed into the
79
+ * step output. The durable driver sets this so a failed `step.do` retries; tests
80
+ * leave it false to preserve the "never wedge" behaviour.
81
+ */
82
+ rethrowAgentErrors?: boolean;
83
+ }
84
+ //# sourceMappingURL=advance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"advance.d.ts","sourceRoot":"","sources":["../../../src/modules/execution/advance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAK3D,MAAM,MAAM,aAAa;AACvB,uEAAuE;AACrE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE;AACtB,0EAA0E;GACxE;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE;AACnD;;;;GAIG;GACD;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE;AAC5D;;;;;;;GAOG;GACD;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE;AAC9C;;;;;;;;;;;GAWG;GACD;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE;AACxF;;;;;;GAMG;GACD;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AACxC,qDAAqD;GACnD;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE;AAClB,0EAA0E;GACxE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE;AACpB,4EAA4E;GAC1E;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAEpB,wDAAwD;AACxD,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAC7B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=advance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"advance.js","sourceRoot":"","sources":["../../../src/modules/execution/advance.ts"],"names":[],"mappings":""}
@@ -0,0 +1,25 @@
1
+ import type { AgentRunResult } from '@cat-factory/kernel';
2
+ /**
3
+ * The text a companion (and the SPA reader, and downstream steps via `priorOutputs`)
4
+ * should review for a finished producer step, or `undefined` when the step's own
5
+ * `output` already IS the work product.
6
+ *
7
+ * A producer that emits a STRUCTURED ARTIFACT (the spec doc, the blueprint tree, …)
8
+ * runs as a container agent: it commits the artifact to the repo and returns its raw
9
+ * Pi transcript summary as `result.output`. That summary is a useless thing to grade
10
+ * — it was what made the spec-companion declare every pass "unreviewable" and loop the
11
+ * producer to its rework cap on every spec task. So whenever a known artifact is
12
+ * present, the reviewable output is a deterministic rendering of the ARTIFACT itself.
13
+ *
14
+ * This is the universal seam: it is keyed off WHICH artifact the result carries, not
15
+ * off a specific `agentKind`, so every artifact-producing agent with a companion —
16
+ * today's spec-writer, and any future one — is covered by rendering its artifact here
17
+ * rather than by another per-agent special case. A producer whose work product is
18
+ * already prose (architect, researcher, the coder's PR summary) carries no artifact
19
+ * field and falls through to `undefined`, keeping its own `output`.
20
+ *
21
+ * Falls back to `undefined` when the artifact is present but won't parse (the in-repo
22
+ * files are committed regardless, so the raw summary is kept rather than nothing).
23
+ */
24
+ export declare function reviewableArtifactOutput(result: AgentRunResult): string | undefined;
25
+ //# sourceMappingURL=artifact-review.logic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact-review.logic.d.ts","sourceRoot":"","sources":["../../../src/modules/execution/artifact-review.logic.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAEzD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,GAAG,SAAS,CAcnF"}
@@ -0,0 +1,39 @@
1
+ import { renderBlueprintForReview, renderSpecForReview, safeParseBlueprintService, safeParseSpecDoc, } from '@cat-factory/contracts';
2
+ /**
3
+ * The text a companion (and the SPA reader, and downstream steps via `priorOutputs`)
4
+ * should review for a finished producer step, or `undefined` when the step's own
5
+ * `output` already IS the work product.
6
+ *
7
+ * A producer that emits a STRUCTURED ARTIFACT (the spec doc, the blueprint tree, …)
8
+ * runs as a container agent: it commits the artifact to the repo and returns its raw
9
+ * Pi transcript summary as `result.output`. That summary is a useless thing to grade
10
+ * — it was what made the spec-companion declare every pass "unreviewable" and loop the
11
+ * producer to its rework cap on every spec task. So whenever a known artifact is
12
+ * present, the reviewable output is a deterministic rendering of the ARTIFACT itself.
13
+ *
14
+ * This is the universal seam: it is keyed off WHICH artifact the result carries, not
15
+ * off a specific `agentKind`, so every artifact-producing agent with a companion —
16
+ * today's spec-writer, and any future one — is covered by rendering its artifact here
17
+ * rather than by another per-agent special case. A producer whose work product is
18
+ * already prose (architect, researcher, the coder's PR summary) carries no artifact
19
+ * field and falls through to `undefined`, keeping its own `output`.
20
+ *
21
+ * Falls back to `undefined` when the artifact is present but won't parse (the in-repo
22
+ * files are committed regardless, so the raw summary is kept rather than nothing).
23
+ */
24
+ export function reviewableArtifactOutput(result) {
25
+ if (result.spec !== undefined) {
26
+ const doc = safeParseSpecDoc(result.spec);
27
+ return doc ? renderSpecForReview(doc) : undefined;
28
+ }
29
+ if (result.blueprintService !== undefined) {
30
+ const service = safeParseBlueprintService(result.blueprintService);
31
+ return service ? renderBlueprintForReview(service) : undefined;
32
+ }
33
+ // `testReport` / `mergeAssessment` carry their own dedicated structured surfaces
34
+ // (the tester result view; the merger is the final step) and no prose companion
35
+ // grades them today. If one ever gains a companion, render it here — the seam, not
36
+ // the call sites, is where a new artifact type is taught to be reviewable.
37
+ return undefined;
38
+ }
39
+ //# sourceMappingURL=artifact-review.logic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"artifact-review.logic.js","sourceRoot":"","sources":["../../../src/modules/execution/artifact-review.logic.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,mBAAmB,EACnB,yBAAyB,EACzB,gBAAgB,GACjB,MAAM,wBAAwB,CAAA;AAG/B;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,wBAAwB,CAAC,MAAsB;IAC7D,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAG,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACzC,OAAO,GAAG,CAAC,CAAC,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IACnD,CAAC;IACD,IAAI,MAAM,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;QAC1C,MAAM,OAAO,GAAG,yBAAyB,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAA;QAClE,OAAO,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAChE,CAAC;IACD,iFAAiF;IACjF,gFAAgF;IAChF,mFAAmF;IACnF,2EAA2E;IAC3E,OAAO,SAAS,CAAA;AAClB,CAAC"}
@@ -0,0 +1,101 @@
1
+ import type { CiCheck } from '@cat-factory/kernel';
2
+ /** The agent kind of the special CI-gate step (polls checks, loops the ci-fixer). */
3
+ export declare const CI_AGENT_KIND = "ci";
4
+ /**
5
+ * The agent kind of the special requirements-review gate step. It is NOT a container /
6
+ * prose agent: the engine runs the inline reviewer (via the requirements module), parks
7
+ * the run for the dedicated review window, and drives the iterative answer → incorporate →
8
+ * re-review loop until it converges (or the human resolves a hit iteration cap). Passes
9
+ * through when the requirements module / reviewer model is not wired.
10
+ */
11
+ export declare const REQUIREMENTS_REVIEW_AGENT_KIND = "requirements-review";
12
+ /**
13
+ * The agent kind of the special clarity-review gate step. Like the requirements reviewer
14
+ * it is an INLINE engine step (not a container/prose agent): the engine runs the inline
15
+ * clarity reviewer (via the clarity module), parks the run for the dedicated review
16
+ * window, and drives the iterative answer → incorporate → re-review loop until it
17
+ * converges. It triages a BUG REPORT for fixability rather than reviewing requirements
18
+ * completeness. Passes through when the clarity module / reviewer model is not wired.
19
+ */
20
+ export declare const CLARITY_REVIEW_AGENT_KIND = "clarity-review";
21
+ /**
22
+ * The agent kind of the read-only `bug-investigator` container agent. It clones the repo,
23
+ * reads the codebase from the raw bug report, and returns a prose report: an enriched bug
24
+ * report plus an OPTIONAL working hypothesis (omitted unless reasonably confident). It
25
+ * makes no commits and opens no PR — it runs the shared read-only `/explore` harness path
26
+ * (like `architect`/`analysis`). Its prose output feeds the downstream clarity reviewer
27
+ * (as the triage subject) and the coder (via `priorOutputs`, as a non-binding lead).
28
+ */
29
+ export declare const BUG_INVESTIGATOR_AGENT_KIND = "bug-investigator";
30
+ /**
31
+ * The agent kind of the container agent that writes the service's unified, in-repo
32
+ * specification (`spec.json`). It runs BEFORE the coder and aggregates the collected
33
+ * requirements of every task under the service frame — including their acceptance
34
+ * scenarios — onto the implementation branch.
35
+ */
36
+ export declare const SPEC_WRITER_AGENT_KIND = "spec-writer";
37
+ /** The agent kind of the container agent that fixes failing CI on the PR branch. */
38
+ export declare const CI_FIXER_AGENT_KIND = "ci-fixer";
39
+ /** The agent kind of the container agent that scores a PR for the merge decision. */
40
+ export declare const MERGER_AGENT_KIND = "merger";
41
+ /**
42
+ * The agent kind of the special `tester` gate step: a container agent that runs the
43
+ * project's tests (local docker-compose infra or an ephemeral env) and returns a
44
+ * structured report. On a withheld greenlight the engine loops the `fixer` agent
45
+ * with the report and re-tests — mirroring the CI gate / ci-fixer loop.
46
+ */
47
+ export declare const TESTER_AGENT_KIND = "tester";
48
+ /**
49
+ * The agent kind of the container agent that applies fixes from a Tester's report to
50
+ * the PR head branch and pushes them back (no new PR), looping with the Tester.
51
+ */
52
+ export declare const FIXER_AGENT_KIND = "fixer";
53
+ /**
54
+ * The agent kind of the special pre-merge gate step: it checks whether the PR can
55
+ * be merged and, on a conflict, loops the conflict-resolver — mirroring the CI gate.
56
+ */
57
+ export declare const CONFLICTS_AGENT_KIND = "conflicts";
58
+ /**
59
+ * The agent kind of the container agent that resolves merge conflicts: it merges
60
+ * the base into the PR branch, fixes the conflicts and pushes back onto the branch.
61
+ */
62
+ export declare const CONFLICT_RESOLVER_AGENT_KIND = "conflict-resolver";
63
+ /**
64
+ * The agent kind of the read-only code-analysis agent that opens the tech-debt
65
+ * recurring pipeline: it inspects the repo and emits a prioritized markdown report
66
+ * (no commits). Reuses the generic container run path — no special engine handling.
67
+ */
68
+ export declare const ANALYSIS_AGENT_KIND = "analysis";
69
+ /**
70
+ * The agent kind of the special `tracker` step: a non-LLM step that files a GitHub
71
+ * issue / Jira ticket from the preceding `analysis` output before implementation,
72
+ * mirroring the special handling of the `ci` gate. Passes through when no tracker
73
+ * is configured for the workspace.
74
+ */
75
+ export declare const TRACKER_AGENT_KIND = "tracker";
76
+ /**
77
+ * The aggregate CI verdict for a PR head commit, derived from its check runs:
78
+ * - `none` — no checks reported (nothing to gate; treated as green).
79
+ * - `pending` — at least one check is still queued/in-progress and none failed.
80
+ * - `success` — every completed check succeeded (or was neutral/skipped) and none pending.
81
+ * - `failure` — at least one check concluded in a non-success terminal state.
82
+ */
83
+ export type CiVerdict = 'none' | 'pending' | 'success' | 'failure';
84
+ /**
85
+ * Reduce a set of check runs to a single verdict. A failure dominates (one red
86
+ * check fails the gate); otherwise a still-running check keeps it pending; with
87
+ * everything completed-and-passing it is green; with no checks at all it is
88
+ * `none` (the engine treats `none` as green so a repo with no CI configured isn't
89
+ * blocked forever).
90
+ */
91
+ export declare function aggregateCi(checks: CiCheck[]): CiVerdict;
92
+ /** Whether a verdict means the gate may advance (green or nothing to gate). */
93
+ export declare function isCiGreen(verdict: CiVerdict): boolean;
94
+ /** The completed-and-non-passing checks behind a `failure` verdict. */
95
+ export declare function listFailingChecks(checks: CiCheck[]): {
96
+ name: string;
97
+ conclusion: string | null;
98
+ }[];
99
+ /** A short, human-readable summary of the failing checks, for the step output / notification. */
100
+ export declare function describeFailingChecks(checks: CiCheck[]): string;
101
+ //# sourceMappingURL=ci.logic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ci.logic.d.ts","sourceRoot":"","sources":["../../../src/modules/execution/ci.logic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAElD,qFAAqF;AACrF,eAAO,MAAM,aAAa,OAAO,CAAA;AAEjC;;;;;;GAMG;AACH,eAAO,MAAM,8BAA8B,wBAAwB,CAAA;AAEnE;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,mBAAmB,CAAA;AAEzD;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,qBAAqB,CAAA;AAE7D;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,gBAAgB,CAAA;AAEnD,oFAAoF;AACpF,eAAO,MAAM,mBAAmB,aAAa,CAAA;AAE7C,qFAAqF;AACrF,eAAO,MAAM,iBAAiB,WAAW,CAAA;AAEzC;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,WAAW,CAAA;AAEzC;;;GAGG;AACH,eAAO,MAAM,gBAAgB,UAAU,CAAA;AAEvC;;;GAGG;AACH,eAAO,MAAM,oBAAoB,cAAc,CAAA;AAE/C;;;GAGG;AACH,eAAO,MAAM,4BAA4B,sBAAsB,CAAA;AAE/D;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,aAAa,CAAA;AAE7C;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,YAAY,CAAA;AAE3C;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAA;AAKlE;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,SAAS,CAYxD;AAED,+EAA+E;AAC/E,wBAAgB,SAAS,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO,CAErD;AAED,uEAAuE;AACvE,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,OAAO,EAAE,GAChB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,EAAE,CAI/C;AAED,iGAAiG;AACjG,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAK/D"}
@@ -0,0 +1,117 @@
1
+ /** The agent kind of the special CI-gate step (polls checks, loops the ci-fixer). */
2
+ export const CI_AGENT_KIND = 'ci';
3
+ /**
4
+ * The agent kind of the special requirements-review gate step. It is NOT a container /
5
+ * prose agent: the engine runs the inline reviewer (via the requirements module), parks
6
+ * the run for the dedicated review window, and drives the iterative answer → incorporate →
7
+ * re-review loop until it converges (or the human resolves a hit iteration cap). Passes
8
+ * through when the requirements module / reviewer model is not wired.
9
+ */
10
+ export const REQUIREMENTS_REVIEW_AGENT_KIND = 'requirements-review';
11
+ /**
12
+ * The agent kind of the special clarity-review gate step. Like the requirements reviewer
13
+ * it is an INLINE engine step (not a container/prose agent): the engine runs the inline
14
+ * clarity reviewer (via the clarity module), parks the run for the dedicated review
15
+ * window, and drives the iterative answer → incorporate → re-review loop until it
16
+ * converges. It triages a BUG REPORT for fixability rather than reviewing requirements
17
+ * completeness. Passes through when the clarity module / reviewer model is not wired.
18
+ */
19
+ export const CLARITY_REVIEW_AGENT_KIND = 'clarity-review';
20
+ /**
21
+ * The agent kind of the read-only `bug-investigator` container agent. It clones the repo,
22
+ * reads the codebase from the raw bug report, and returns a prose report: an enriched bug
23
+ * report plus an OPTIONAL working hypothesis (omitted unless reasonably confident). It
24
+ * makes no commits and opens no PR — it runs the shared read-only `/explore` harness path
25
+ * (like `architect`/`analysis`). Its prose output feeds the downstream clarity reviewer
26
+ * (as the triage subject) and the coder (via `priorOutputs`, as a non-binding lead).
27
+ */
28
+ export const BUG_INVESTIGATOR_AGENT_KIND = 'bug-investigator';
29
+ /**
30
+ * The agent kind of the container agent that writes the service's unified, in-repo
31
+ * specification (`spec.json`). It runs BEFORE the coder and aggregates the collected
32
+ * requirements of every task under the service frame — including their acceptance
33
+ * scenarios — onto the implementation branch.
34
+ */
35
+ export const SPEC_WRITER_AGENT_KIND = 'spec-writer';
36
+ /** The agent kind of the container agent that fixes failing CI on the PR branch. */
37
+ export const CI_FIXER_AGENT_KIND = 'ci-fixer';
38
+ /** The agent kind of the container agent that scores a PR for the merge decision. */
39
+ export const MERGER_AGENT_KIND = 'merger';
40
+ /**
41
+ * The agent kind of the special `tester` gate step: a container agent that runs the
42
+ * project's tests (local docker-compose infra or an ephemeral env) and returns a
43
+ * structured report. On a withheld greenlight the engine loops the `fixer` agent
44
+ * with the report and re-tests — mirroring the CI gate / ci-fixer loop.
45
+ */
46
+ export const TESTER_AGENT_KIND = 'tester';
47
+ /**
48
+ * The agent kind of the container agent that applies fixes from a Tester's report to
49
+ * the PR head branch and pushes them back (no new PR), looping with the Tester.
50
+ */
51
+ export const FIXER_AGENT_KIND = 'fixer';
52
+ /**
53
+ * The agent kind of the special pre-merge gate step: it checks whether the PR can
54
+ * be merged and, on a conflict, loops the conflict-resolver — mirroring the CI gate.
55
+ */
56
+ export const CONFLICTS_AGENT_KIND = 'conflicts';
57
+ /**
58
+ * The agent kind of the container agent that resolves merge conflicts: it merges
59
+ * the base into the PR branch, fixes the conflicts and pushes back onto the branch.
60
+ */
61
+ export const CONFLICT_RESOLVER_AGENT_KIND = 'conflict-resolver';
62
+ /**
63
+ * The agent kind of the read-only code-analysis agent that opens the tech-debt
64
+ * recurring pipeline: it inspects the repo and emits a prioritized markdown report
65
+ * (no commits). Reuses the generic container run path — no special engine handling.
66
+ */
67
+ export const ANALYSIS_AGENT_KIND = 'analysis';
68
+ /**
69
+ * The agent kind of the special `tracker` step: a non-LLM step that files a GitHub
70
+ * issue / Jira ticket from the preceding `analysis` output before implementation,
71
+ * mirroring the special handling of the `ci` gate. Passes through when no tracker
72
+ * is configured for the workspace.
73
+ */
74
+ export const TRACKER_AGENT_KIND = 'tracker';
75
+ /** Conclusions GitHub reports for a *completed* check that are NOT failures. */
76
+ const PASSING_CONCLUSIONS = new Set(['success', 'neutral', 'skipped']);
77
+ /**
78
+ * Reduce a set of check runs to a single verdict. A failure dominates (one red
79
+ * check fails the gate); otherwise a still-running check keeps it pending; with
80
+ * everything completed-and-passing it is green; with no checks at all it is
81
+ * `none` (the engine treats `none` as green so a repo with no CI configured isn't
82
+ * blocked forever).
83
+ */
84
+ export function aggregateCi(checks) {
85
+ if (checks.length === 0)
86
+ return 'none';
87
+ let pending = false;
88
+ for (const check of checks) {
89
+ if (check.status !== 'completed') {
90
+ pending = true;
91
+ continue;
92
+ }
93
+ const conclusion = check.conclusion ?? '';
94
+ if (!PASSING_CONCLUSIONS.has(conclusion))
95
+ return 'failure';
96
+ }
97
+ return pending ? 'pending' : 'success';
98
+ }
99
+ /** Whether a verdict means the gate may advance (green or nothing to gate). */
100
+ export function isCiGreen(verdict) {
101
+ return verdict === 'success' || verdict === 'none';
102
+ }
103
+ /** The completed-and-non-passing checks behind a `failure` verdict. */
104
+ export function listFailingChecks(checks) {
105
+ return checks
106
+ .filter((c) => c.status === 'completed' && !PASSING_CONCLUSIONS.has(c.conclusion ?? ''))
107
+ .map((c) => ({ name: c.name, conclusion: c.conclusion }));
108
+ }
109
+ /** A short, human-readable summary of the failing checks, for the step output / notification. */
110
+ export function describeFailingChecks(checks) {
111
+ const failing = listFailingChecks(checks);
112
+ if (failing.length === 0)
113
+ return 'CI reported a failure.';
114
+ const names = failing.map((c) => `${c.name} (${c.conclusion ?? 'failure'})`).join(', ');
115
+ return `Failing checks: ${names}`;
116
+ }
117
+ //# sourceMappingURL=ci.logic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ci.logic.js","sourceRoot":"","sources":["../../../src/modules/execution/ci.logic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import type { ExecutionService } from './ExecutionService.js';
2
+ /** Poll cadence + budgets for the gates a parked run waits on. */
3
+ export interface DriveConfig {
4
+ jobPollIntervalMs: number;
5
+ jobMaxPolls: number;
6
+ jobPollFailureTolerance: number;
7
+ ciPollIntervalMs: number;
8
+ ciMaxPolls: number;
9
+ }
10
+ /** Minimal structured logger the driver needs (pino is structurally compatible). */
11
+ export interface DriveLogger {
12
+ info(obj: unknown, msg?: string): void;
13
+ }
14
+ /** Runtime seams the driver loop needs; both have inert defaults. */
15
+ export interface DriveOptions {
16
+ /**
17
+ * How to wait between gate polls. Orchestration is runtime-neutral (no timers), so
18
+ * the default resolves INSTANTLY; the Node service injects a real `setTimeout` sleep
19
+ * (see its `drive.ts` wrapper), and the conformance harness keeps the instant default
20
+ * to drive the deterministic fakes without real waiting.
21
+ */
22
+ sleep?: (ms: number) => Promise<void>;
23
+ /** Where to log lifecycle breadcrumbs. Defaults to a no-op. */
24
+ log?: DriveLogger;
25
+ }
26
+ /** What a drive ended on, so the runner can schedule follow-up work (a decision timeout). */
27
+ export interface DriveOutcome {
28
+ /** Set when the run parked awaiting a human decision/approval with this id. */
29
+ parkedDecisionId?: string;
30
+ }
31
+ /**
32
+ * Drive one run to a standstill. The runtime-neutral driver loop: it contains NO
33
+ * business logic — every decision lives in {@link ExecutionService} — and uses plain
34
+ * async sleeps, so it is the exact analogue of the Cloudflare ExecutionWorkflow (which
35
+ * wraps the same advance/poll calls in durable steps). The Node service's pg-boss
36
+ * worker runs it with a real sleep + pino logger; the cross-runtime conformance harness
37
+ * runs the SAME function (instant sleep, no-op log) against each facade's real store, so
38
+ * the suite exercises the production driver rather than a hand-rolled twin — which is how
39
+ * the companion-failure clobber (a second `failRun` overwriting the rich record with a
40
+ * generic one) once slipped past the suite.
41
+ *
42
+ * On a human decision it parks (returning the id so the caller can arm a timeout); the
43
+ * pg-boss runner re-enqueues an advance when the decision is resolved. All run state
44
+ * lives in the store, so a re-run after a crash simply reads the current state.
45
+ */
46
+ export declare function driveExecution(exec: ExecutionService, workspaceId: string, executionId: string, cfg: DriveConfig, opts?: DriveOptions): Promise<DriveOutcome>;
47
+ //# sourceMappingURL=drive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drive.d.ts","sourceRoot":"","sources":["../../../src/modules/execution/drive.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAE7D,kEAAkE;AAClE,MAAM,WAAW,WAAW;IAC1B,iBAAiB,EAAE,MAAM,CAAA;IACzB,WAAW,EAAE,MAAM,CAAA;IACnB,uBAAuB,EAAE,MAAM,CAAA;IAC/B,gBAAgB,EAAE,MAAM,CAAA;IACxB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,oFAAoF;AACpF,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACvC;AAED,qEAAqE;AACrE,MAAM,WAAW,YAAY;IAC3B;;;;;OAKG;IACH,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,+DAA+D;IAC/D,GAAG,CAAC,EAAE,WAAW,CAAA;CAClB;AAED,6FAA6F;AAC7F,MAAM,WAAW,YAAY;IAC3B,+EAA+E;IAC/E,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAKD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,gBAAgB,EACtB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,WAAW,EAChB,IAAI,GAAE,YAAiB,GACtB,OAAO,CAAC,YAAY,CAAC,CAkHvB"}
@@ -0,0 +1,112 @@
1
+ const instantSleep = () => Promise.resolve();
2
+ const noopLogger = { info() { } };
3
+ /**
4
+ * Drive one run to a standstill. The runtime-neutral driver loop: it contains NO
5
+ * business logic — every decision lives in {@link ExecutionService} — and uses plain
6
+ * async sleeps, so it is the exact analogue of the Cloudflare ExecutionWorkflow (which
7
+ * wraps the same advance/poll calls in durable steps). The Node service's pg-boss
8
+ * worker runs it with a real sleep + pino logger; the cross-runtime conformance harness
9
+ * runs the SAME function (instant sleep, no-op log) against each facade's real store, so
10
+ * the suite exercises the production driver rather than a hand-rolled twin — which is how
11
+ * the companion-failure clobber (a second `failRun` overwriting the rich record with a
12
+ * generic one) once slipped past the suite.
13
+ *
14
+ * On a human decision it parks (returning the id so the caller can arm a timeout); the
15
+ * pg-boss runner re-enqueues an advance when the decision is resolved. All run state
16
+ * lives in the store, so a re-run after a crash simply reads the current state.
17
+ */
18
+ export async function driveExecution(exec, workspaceId, executionId, cfg, opts = {}) {
19
+ const sleep = opts.sleep ?? instantSleep;
20
+ const log = opts.log ?? noopLogger;
21
+ const fail = (message, kind = 'agent', detail = null) => exec.failRun(workspaceId, executionId, message, kind, detail);
22
+ // Poll a parked gate (job / CI / conflicts) until it yields a non-awaiting result
23
+ // or the budget is spent. Tolerates a bounded run of status-read failures.
24
+ const pollUntil = async (awaiting, poll, intervalMs, maxPolls, label, onExhausted) => {
25
+ let readFailures = 0;
26
+ for (let p = 0; p < maxPolls; p++) {
27
+ await sleep(intervalMs);
28
+ let result;
29
+ try {
30
+ result = await poll();
31
+ }
32
+ catch {
33
+ readFailures += 1;
34
+ if (readFailures >= cfg.jobPollFailureTolerance) {
35
+ await fail(`${label} status was unreadable (${readFailures} polls)`, 'timeout');
36
+ return null;
37
+ }
38
+ continue;
39
+ }
40
+ readFailures = 0;
41
+ if (result.kind !== awaiting)
42
+ return result;
43
+ }
44
+ // Budget spent. A gate may resolve exhaustion itself (a watch gate PASSES rather than
45
+ // timing out) — let it; otherwise fail the run as a generic timeout.
46
+ if (onExhausted)
47
+ return onExhausted();
48
+ await fail(`${label} did not settle within its polling budget`, 'timeout');
49
+ return null;
50
+ };
51
+ for (;;) {
52
+ let result;
53
+ try {
54
+ result = await exec.advanceInstance(workspaceId, executionId, { rethrowAgentErrors: true });
55
+ }
56
+ catch (error) {
57
+ await fail(error instanceof Error ? error.message : String(error));
58
+ return {};
59
+ }
60
+ // Drain whatever gate the step parked on. A gate poll can resolve to a DIFFERENT
61
+ // gate — e.g. a `ci` step that finds CI red dispatches a `ci-fixer` and returns
62
+ // `awaiting_job` — so loop until the result is no longer an awaiting_* gate rather
63
+ // than relying on the next `advanceInstance` to re-establish the poll (which is why
64
+ // the order of these checks must not matter). `pollUntil` itself is bounded, so the
65
+ // outer guard only backstops a pathological gate↔gate ping-pong.
66
+ let gateHops = 0;
67
+ const MAX_GATE_HOPS = 64;
68
+ while (gateHops++ < MAX_GATE_HOPS) {
69
+ if (result.kind === 'awaiting_job') {
70
+ const next = await pollUntil('awaiting_job', () => exec.pollAgentJob(workspaceId, executionId), cfg.jobPollIntervalMs, cfg.jobMaxPolls, 'Implementation job');
71
+ if (!next)
72
+ return {};
73
+ result = next;
74
+ continue;
75
+ }
76
+ // A polling gate step (`ci` / `conflicts`): re-run its precheck between sleeps;
77
+ // which gate is resolved inside `pollGate` from the current step, so one branch
78
+ // drives both.
79
+ if (result.kind === 'awaiting_gate') {
80
+ const next = await pollUntil('awaiting_gate', () => exec.pollGate(workspaceId, executionId), cfg.ciPollIntervalMs, cfg.ciMaxPolls, 'Gate precheck', () => exec.resolveGatePollExhaustion(workspaceId, executionId));
81
+ if (!next)
82
+ return {};
83
+ result = next;
84
+ continue;
85
+ }
86
+ break;
87
+ }
88
+ if (result.kind === 'job_failed') {
89
+ // Single `failRun` funnel for a terminal step failure. An inline gate that already
90
+ // knows the precise classification + diagnostic carries them on the result
91
+ // (`failureKind`/`detail`) — e.g. an unparseable companion verdict
92
+ // (`companion_rejected`, with its raw reply as detail) — so the run records the
93
+ // accurate kind, hint and detail instead of a generic "container reported a
94
+ // failure". Defaults to `job_failed` for a genuine container-job failure.
95
+ await fail(result.error, result.failureKind ?? 'job_failed', result.detail ?? null);
96
+ return {};
97
+ }
98
+ if (result.kind === 'job_evicted') {
99
+ await fail(result.error, 'evicted');
100
+ return {};
101
+ }
102
+ // done / noop / paused: stop. awaiting_decision: park (resumed on signalDecision).
103
+ if (result.kind === 'done' || result.kind === 'noop' || result.kind === 'paused')
104
+ return {};
105
+ if (result.kind === 'awaiting_decision') {
106
+ log.info({ workspaceId, executionId, decisionId: result.decisionId }, 'run parked on decision');
107
+ return { parkedDecisionId: result.decisionId };
108
+ }
109
+ // 'continue': loop and advance the next step.
110
+ }
111
+ }
112
+ //# sourceMappingURL=drive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drive.js","sourceRoot":"","sources":["../../../src/modules/execution/drive.ts"],"names":[],"mappings":"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"}