@cat-factory/orchestration 0.37.2 → 0.38.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.
@@ -16,6 +16,7 @@ import { RunStateMachine } from './RunStateMachine.js';
16
16
  import { inferTechnicalLabel } from './technical.logic.js';
17
17
  import { MergeResolver } from './MergeResolver.js';
18
18
  import { ReviewGateController } from './ReviewGateController.js';
19
+ import { BrainstormActions, ClarityReviewActions, RequirementReviewActions, } from './gate-window-facades.js';
19
20
  import { TesterController } from './TesterController.js';
20
21
  import { HumanTestController } from './HumanTestController.js';
21
22
  import { VisualConfirmationController } from './VisualConfirmationController.js';
@@ -76,7 +77,6 @@ export class ExecutionService {
76
77
  blockRepository;
77
78
  pipelineRepository;
78
79
  executionRepository;
79
- accountRepository;
80
80
  idGenerator;
81
81
  clock;
82
82
  /** The pure step/cursor mutators (start/finish/park/reset + the companion rework loop). */
@@ -92,8 +92,6 @@ export class ExecutionService {
92
92
  clarityReviewService;
93
93
  brainstormServices;
94
94
  environmentProvisioning;
95
- environmentTeardown;
96
- branchUpdater;
97
95
  /** Assembles the per-step agent context (requirements, docs, env, service frame, fragments). */
98
96
  contextBuilder;
99
97
  /** Resolves a `merger` step's assessment into an auto-merge or a `merge_review` notification. */
@@ -115,6 +113,12 @@ export class ExecutionService {
115
113
  /** The two brainstorm (structured-dialogue) subjects for {@link reviewGate}, by stage. */
116
114
  requirementsBrainstormKind;
117
115
  architectureBrainstormKind;
116
+ /** Requirements-review window actions (exposed via {@link requirementsReview}). */
117
+ requirementsReviewActions;
118
+ /** Clarity-review (bug triage) window actions (exposed via {@link clarityReview}). */
119
+ clarityReviewActions;
120
+ /** Brainstorm window actions (exposed via {@link brainstorm}). */
121
+ brainstormActions;
118
122
  blueprintReconciler;
119
123
  notificationService;
120
124
  workspaceSettingsService;
@@ -162,7 +166,6 @@ export class ExecutionService {
162
166
  this.blockRepository = blockRepository;
163
167
  this.pipelineRepository = pipelineRepository;
164
168
  this.executionRepository = executionRepository;
165
- this.accountRepository = accountRepository;
166
169
  this.idGenerator = idGenerator;
167
170
  this.clock = clock;
168
171
  this.stepGraph = new StepGraph(clock);
@@ -189,8 +192,6 @@ export class ExecutionService {
189
192
  this.clarityReviewService = clarityReviewService;
190
193
  this.brainstormServices = brainstormServices;
191
194
  this.environmentProvisioning = environmentProvisioning;
192
- this.environmentTeardown = environmentTeardown;
193
- this.branchUpdater = branchUpdater;
194
195
  this.contextBuilder = new AgentContextBuilder({
195
196
  workspaceRepository,
196
197
  blockRepository,
@@ -290,6 +291,12 @@ export class ExecutionService {
290
291
  this.clarityKind = this.buildClarityKind();
291
292
  this.requirementsBrainstormKind = this.buildBrainstormKind('requirements', REQUIREMENTS_BRAINSTORM_AGENT_KIND);
292
293
  this.architectureBrainstormKind = this.buildBrainstormKind('architecture', ARCHITECTURE_BRAINSTORM_AGENT_KIND);
294
+ // Group the per-feature gate-window actions into cohesive sub-facades (exposed as
295
+ // getters below) so they stop bloating the engine's public surface as ~30 near-identical
296
+ // 3-line delegations. They close over the same shared collaborators the handlers use.
297
+ this.requirementsReviewActions = new RequirementReviewActions(this.reviewGate, this.requirementsKind);
298
+ this.clarityReviewActions = new ClarityReviewActions(this.reviewGate, this.clarityKind);
299
+ this.brainstormActions = new BrainstormActions(this.reviewGate, (stage) => this.brainstormKindFor(stage));
293
300
  this.blueprintReconciler = blueprintReconciler;
294
301
  this.notificationService = notificationService;
295
302
  this.workspaceSettingsService = workspaceSettingsService;
@@ -306,6 +313,30 @@ export class ExecutionService {
306
313
  this.resolveRequireEnvironmentProvider = resolveRequireEnvironmentProvider;
307
314
  this.assertAgentBackendConfigured = assertAgentBackendConfigured;
308
315
  }
316
+ // ---- gate-window action sub-facades -------------------------------------
317
+ // Per-feature groupings of the dedicated review/test window actions, consumed by the
318
+ // matching server controllers. See {@link gate-window-facades}. The `executionService` is
319
+ // still the single injected object, so the runtimes stay symmetric (no composition-root edit).
320
+ /** Requirements-review window actions (run / incorporate / re-review / proceed / …). */
321
+ get requirementsReview() {
322
+ return this.requirementsReviewActions;
323
+ }
324
+ /** Clarity-review (bug-report triage) window actions. */
325
+ get clarityReview() {
326
+ return this.clarityReviewActions;
327
+ }
328
+ /** Brainstorm (structured-dialogue) window actions, keyed by stage. */
329
+ get brainstorm() {
330
+ return this.brainstormActions;
331
+ }
332
+ /** Human-testing gate window actions (confirm / request-fix / pull-main / recreate / destroy). */
333
+ get humanTest() {
334
+ return this.humanTestController;
335
+ }
336
+ /** Visual-confirmation gate window actions (approve / request-fix / recapture). */
337
+ get visualConfirm() {
338
+ return this.visualConfirmationController;
339
+ }
309
340
  requireWorkspace(workspaceId) {
310
341
  return requireWorkspace(this.workspaceRepository, workspaceId);
311
342
  }
@@ -2813,83 +2844,13 @@ export class ExecutionService {
2813
2844
  ? this.architectureBrainstormKind
2814
2845
  : this.requirementsBrainstormKind;
2815
2846
  }
2816
- /** Run a fresh brainstorm pass over a block + stage (off-path inspector / window surface). */
2817
- reviewBrainstorm(workspaceId, blockId, stage) {
2818
- return this.reviewGate.review(this.brainstormKindFor(stage), workspaceId, blockId);
2819
- }
2820
- /** Incorporate the human's picks ASYNCHRONOUSLY (the brainstorm mirror of {@link incorporateRequirements}). */
2821
- incorporateBrainstorm(workspaceId, blockId, stage, feedback) {
2822
- return this.reviewGate.incorporate(this.brainstormKindFor(stage), workspaceId, blockId, feedback);
2823
- }
2824
- /** Re-run the brainstorm against the converged direction (one more pass). */
2825
- reReviewBrainstorm(workspaceId, blockId, stage) {
2826
- return this.reviewGate.reReview(this.brainstormKindFor(stage), workspaceId, blockId);
2827
- }
2828
- /** Proceed: settle the brainstorm (last converged direction wins downstream) and advance. */
2829
- proceedBrainstorm(workspaceId, blockId, stage) {
2830
- return this.reviewGate.proceed(this.brainstormKindFor(stage), workspaceId, blockId);
2831
- }
2832
- /** Resolve a brainstorm that hit its iteration cap (extra-round / proceed / stop-reset). */
2833
- resolveBrainstormExceeded(workspaceId, blockId, stage, choice) {
2834
- return this.reviewGate.resolveExceeded(this.brainstormKindFor(stage), workspaceId, blockId, choice);
2835
- }
2836
- /**
2837
- * Run a fresh reviewer pass over a block's collected requirements, snapshotting the
2838
- * task's merge-preset knobs (iteration budget + tolerated severity) onto the review.
2839
- * Shared by the pipeline gate and the off-path inspector "Run review" surface, so both
2840
- * honour the task's preset identically.
2841
- */
2842
- reviewRequirements(workspaceId, blockId) {
2843
- return this.reviewGate.review(this.requirementsKind, workspaceId, blockId);
2844
- }
2845
- /**
2846
- * Incorporate the human's settled answers ASYNCHRONOUSLY. Validates that every finding is
2847
- * answered/dismissed, flags the review `incorporating`, records the intent on the parked
2848
- * gate step, and signals the durable driver to wake — which folds the answers and
2849
- * re-reviews in the background. Off-path (no parked run) the fold + re-review run inline.
2850
- */
2851
- incorporateRequirements(workspaceId, blockId, feedback) {
2852
- return this.reviewGate.incorporate(this.requirementsKind, workspaceId, blockId, feedback);
2853
- }
2854
- /**
2855
- * Re-review the incorporated document (one more reviewer pass). On convergence
2856
- * (`incorporated`) the parked run advances; otherwise the window shows the next cycle
2857
- * (`ready`) or the iteration-cap choices (`exceeded`).
2858
- */
2859
- reReviewRequirements(workspaceId, blockId) {
2860
- return this.reviewGate.reReview(this.requirementsKind, workspaceId, blockId);
2861
- }
2862
- /**
2863
- * Proceed: settle the requirements (the last incorporated doc, if any, becomes what
2864
- * downstream agents consume) and advance the parked run.
2865
- */
2866
- proceedRequirements(workspaceId, blockId) {
2867
- return this.reviewGate.proceed(this.requirementsKind, workspaceId, blockId);
2868
- }
2869
- /**
2870
- * Ask the Requirement Writer to recommend answers for a batch of findings ASYNCHRONOUSLY:
2871
- * append `pending` placeholder recommendations at once and signal the durable driver to run
2872
- * the Writer per finding in the background (filling them in + notifying when done). Returns the
2873
- * review with the placeholders so the SPA shows "generating…" and hands the user back.
2874
- */
2875
- requestRecommendations(workspaceId, blockId, itemIds, note) {
2876
- return this.reviewGate.requestRecommendations(this.requirementsKind, workspaceId, blockId, itemIds, note);
2877
- }
2878
- /**
2879
- * Re-request a single recommendation with a "do it differently" note — resets it to `pending`
2880
- * and drives the Writer through the same async path. Review-scoped (the re-request endpoint
2881
- * addresses the recommendation by review id).
2882
- */
2883
- reRequestRecommendation(workspaceId, reviewId, recId, note) {
2884
- return this.reviewGate.reRequestRecommendation(this.requirementsKind, workspaceId, reviewId, recId, note);
2885
- }
2886
2847
  /**
2887
2848
  * Route an iteration-cap resolution to its gate-specific handlers. `stop-reset` is
2888
2849
  * uniform across gates: cancel the run and return the block to phase zero (editable),
2889
2850
  * keeping whatever reference artifact each gate persists (the requirements doc on its
2890
2851
  * own table; a companion's producer output on its branch). Shared by the requirements
2891
- * gate ({@link resolveRequirementsExceeded}) and the companion gate
2892
- * ({@link resolveCompanionExceeded}) so the three-way choice lives in one place.
2852
+ * gate (`requirementsReview.resolveExceeded`, via {@link ReviewGateController}) and the
2853
+ * companion gate ({@link resolveCompanionExceeded}) so the three-way choice lives in one place.
2893
2854
  */
2894
2855
  async dispatchIterationCap(workspaceId, blockId, choice, handlers) {
2895
2856
  if (choice === 'extra-round') {
@@ -2903,18 +2864,11 @@ export class ExecutionService {
2903
2864
  await this.cancel(workspaceId, blockId);
2904
2865
  }
2905
2866
  }
2906
- /**
2907
- * Resolve a requirements review that hit its iteration cap: grant one more round,
2908
- * proceed with the last incorporated doc, or stop the task and reset it to phase zero.
2909
- */
2910
- resolveRequirementsExceeded(workspaceId, blockId, choice) {
2911
- return this.reviewGate.resolveExceeded(this.requirementsKind, workspaceId, blockId, choice);
2912
- }
2913
2867
  /**
2914
2868
  * Resolve a companion step parked at its automatic-rework cap (`companion.exceeded`):
2915
2869
  * grant one more round, proceed accepting the producer's current output, or stop the
2916
- * task and reset it to phase zero. The companion mirror of
2917
- * {@link resolveRequirementsExceeded}, sharing the iteration-cap dispatch + the
2870
+ * task and reset it to phase zero. The companion mirror of the requirements
2871
+ * iteration-cap resolution (`requirementsReview.resolveExceeded`), sharing the iteration-cap dispatch + the
2918
2872
  * gate-resume plumbing. Idempotent — an already-resolved gate returns the instance
2919
2873
  * unchanged. Scoped by execution + approval id (the execution controller surface),
2920
2874
  * since a companion gate is not block-addressed like the requirements window.
@@ -2990,69 +2944,9 @@ export class ExecutionService {
2990
2944
  const instance = await this.executionRepository.get(workspaceId, block.executionId);
2991
2945
  return instance ? this.investigationFor(instance) : undefined;
2992
2946
  }
2993
- /**
2994
- * Run a fresh clarity reviewer pass over a block's bug report, snapshotting the task's
2995
- * merge-preset knobs (iteration budget + tolerated severity) and threading in any
2996
- * `bug-investigator` output as the triage subject. Shared by the gate + the off-path
2997
- * inspector "Run review" surface.
2998
- */
2999
- reviewClarity(workspaceId, blockId) {
3000
- return this.reviewGate.review(this.clarityKind, workspaceId, blockId);
3001
- }
3002
- /** Incorporate the human's settled answers ASYNCHRONOUSLY (the clarity mirror of {@link incorporateRequirements}). */
3003
- incorporateClarity(workspaceId, blockId, feedback) {
3004
- return this.reviewGate.incorporate(this.clarityKind, workspaceId, blockId, feedback);
3005
- }
3006
- /** Re-review the clarified report (one more pass). On convergence the parked run advances. */
3007
- reReviewClarity(workspaceId, blockId) {
3008
- return this.reviewGate.reReview(this.clarityKind, workspaceId, blockId);
3009
- }
3010
- /** Proceed: settle the clarity review and advance the parked run. */
3011
- proceedClarity(workspaceId, blockId) {
3012
- return this.reviewGate.proceed(this.clarityKind, workspaceId, blockId);
3013
- }
3014
- /** Resolve a clarity review that hit its iteration cap (extra-round / proceed / stop-reset). */
3015
- resolveClarityExceeded(workspaceId, blockId, choice) {
3016
- return this.reviewGate.resolveExceeded(this.clarityKind, workspaceId, blockId, choice);
3017
- }
3018
- // ---- human-testing gate actions (driven from the dedicated window) -------
3019
- // Each mutates the parked gate step and wakes the durable driver, which re-enters the gate
3020
- // and performs the (env / helper) work; see {@link HumanTestController}.
3021
- /** Confirm the change works: tear the ephemeral env down and advance the run. */
3022
- confirmHumanTest(workspaceId, blockId) {
3023
- return this.humanTestController.confirm(workspaceId, blockId);
3024
- }
3025
- /** Submit findings and request a fix: dispatch the Tester's `fixer`, then rebuild the env. */
3026
- requestHumanTestFix(workspaceId, blockId, findings) {
3027
- return this.humanTestController.requestFix(workspaceId, blockId, findings);
3028
- }
3029
- /** Pull the repo default branch into the PR branch + redeploy (conflict → conflict-resolver). */
3030
- pullMainHumanTest(workspaceId, blockId) {
3031
- return this.humanTestController.pullMain(workspaceId, blockId);
3032
- }
3033
- /** Rebuild the ephemeral environment on demand. */
3034
- recreateHumanTestEnv(workspaceId, blockId) {
3035
- return this.humanTestController.recreateEnvironment(workspaceId, blockId);
3036
- }
3037
- /** Destroy the ephemeral environment on demand (the run stays parked). */
3038
- destroyHumanTestEnv(workspaceId, blockId) {
3039
- return this.humanTestController.destroyEnvironment(workspaceId, blockId);
3040
- }
3041
- // ---- visual-confirmation gate actions (driven from the dedicated window) --
3042
- // Each mutates the parked gate step and wakes the durable driver; see
3043
- // {@link VisualConfirmationController}.
3044
- /** Approve the reviewed screenshots: advance the run. */
3045
- approveVisualConfirm(workspaceId, blockId) {
3046
- return this.visualConfirmationController.approve(workspaceId, blockId);
3047
- }
3048
- /** Submit findings and request a fix: dispatch the Tester's `fixer`, then re-park. */
3049
- requestVisualConfirmFix(workspaceId, blockId, findings) {
3050
- return this.visualConfirmationController.requestFix(workspaceId, blockId, findings);
3051
- }
3052
- /** Refresh the screenshot pairs from the latest UI-tester report. */
3053
- recaptureVisualConfirm(workspaceId, blockId) {
3054
- return this.visualConfirmationController.recapture(workspaceId, blockId);
3055
- }
2947
+ // The clarity / human-testing / visual-confirmation gate-window actions now live on the
2948
+ // per-feature sub-facades (`clarityReview` / `humanTest` / `visualConfirm`); see the getters
2949
+ // above and {@link gate-window-facades}.
3056
2950
  /**
3057
2951
  * Dispatch the `fixer` against the human-review gate's PR branch from a human's freeform
3058
2952
  * instructions — bypassing the precheck + grace window. Parks a `pendingFix` on the gate step,