@cat-factory/orchestration 0.327.0 → 0.329.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.
- package/dist/modules/execution/CredentialWaitController.d.ts +51 -0
- package/dist/modules/execution/CredentialWaitController.d.ts.map +1 -0
- package/dist/modules/execution/CredentialWaitController.js +140 -0
- package/dist/modules/execution/CredentialWaitController.js.map +1 -0
- package/dist/modules/execution/ExecutionService.d.ts +1230 -0
- package/dist/modules/execution/ExecutionService.d.ts.map +1 -1
- package/dist/modules/execution/ExecutionService.js +17 -5
- package/dist/modules/execution/ExecutionService.js.map +1 -1
- package/dist/modules/execution/ReviewGateController.d.ts +11 -1
- package/dist/modules/execution/ReviewGateController.d.ts.map +1 -1
- package/dist/modules/execution/ReviewGateController.js +29 -3
- package/dist/modules/execution/ReviewGateController.js.map +1 -1
- package/dist/modules/execution/RunStateMachine.d.ts +6 -0
- package/dist/modules/execution/RunStateMachine.d.ts.map +1 -1
- package/dist/modules/execution/RunStateMachine.js +13 -3
- package/dist/modules/execution/RunStateMachine.js.map +1 -1
- package/dist/modules/execution/StepDecisionController.d.ts.map +1 -1
- package/dist/modules/execution/StepDecisionController.js +1 -0
- package/dist/modules/execution/StepDecisionController.js.map +1 -1
- package/dist/modules/execution/gate-window-controllers.d.ts +15 -0
- package/dist/modules/execution/gate-window-controllers.d.ts.map +1 -1
- package/dist/modules/execution/gate-window-controllers.js +16 -0
- package/dist/modules/execution/gate-window-controllers.js.map +1 -1
- package/dist/modules/execution/gate-window-facades.d.ts +4 -2
- package/dist/modules/execution/gate-window-facades.d.ts.map +1 -1
- package/dist/modules/execution/gate-window-facades.js +5 -4
- package/dist/modules/execution/gate-window-facades.js.map +1 -1
- package/dist/modules/execution/step-park.logic.d.ts +1 -1
- package/dist/modules/execution/step-park.logic.d.ts.map +1 -1
- package/dist/modules/execution/step-park.logic.js +5 -0
- package/dist/modules/execution/step-park.logic.js.map +1 -1
- package/dist/modules/requirements/RequirementReviewService.d.ts +2 -0
- package/dist/modules/requirements/RequirementReviewService.d.ts.map +1 -1
- package/dist/modules/requirements/RequirementReviewService.js +3 -0
- package/dist/modules/requirements/RequirementReviewService.js.map +1 -1
- package/dist/modules/requirements/requirements.logic.d.ts +7 -1
- package/dist/modules/requirements/requirements.logic.d.ts.map +1 -1
- package/dist/modules/requirements/requirements.logic.js +18 -2
- package/dist/modules/requirements/requirements.logic.js.map +1 -1
- package/dist/modules/review/IterativeReviewService.d.ts +7 -1
- package/dist/modules/review/IterativeReviewService.d.ts.map +1 -1
- package/dist/modules/review/IterativeReviewService.js +19 -6
- package/dist/modules/review/IterativeReviewService.js.map +1 -1
- package/dist/modules/review/follow-up-bar.logic.d.ts +32 -0
- package/dist/modules/review/follow-up-bar.logic.d.ts.map +1 -0
- package/dist/modules/review/follow-up-bar.logic.js +62 -0
- package/dist/modules/review/follow-up-bar.logic.js.map +1 -0
- package/package.json +11 -11
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { Clock, ExecutionInstance, ExecutionRepository, Logger, WorkRunner } from '@cat-factory/kernel';
|
|
2
|
+
import type { AdvanceResult } from './advance.js';
|
|
3
|
+
import type { RunStateMachine } from './RunStateMachine.js';
|
|
4
|
+
import type { StepGraph } from './StepGraph.js';
|
|
5
|
+
export interface CredentialWaitControllerDeps {
|
|
6
|
+
stateMachine: RunStateMachine;
|
|
7
|
+
stepGraph: StepGraph;
|
|
8
|
+
executionRepository: ExecutionRepository;
|
|
9
|
+
clock: Clock;
|
|
10
|
+
workRunner: WorkRunner;
|
|
11
|
+
logger?: Logger;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Parks a run whose personal-subscription credential lapsed, and resumes it.
|
|
15
|
+
*
|
|
16
|
+
* A run on an individual-usage model leases its initiator's credential at every dispatch, from an
|
|
17
|
+
* activation with a fixed lifetime. Whatever advanced the run to that dispatch (a human answering
|
|
18
|
+
* a review, a background re-review converging, a timer) is irrelevant here: the lease is refused,
|
|
19
|
+
* and the step parks on the generic approval with `credentialWait` set, instead of failing the run.
|
|
20
|
+
* The person answers it with {@link resume}, which re-mints the activation from their personal
|
|
21
|
+
* password before re-dispatching.
|
|
22
|
+
*
|
|
23
|
+
* {@link guard} is the ONE place the refusal is recognised. The engine routes every call that can
|
|
24
|
+
* dispatch (advance and the three poll entry points) through it, so no dispatch site and no
|
|
25
|
+
* run-advancing route has to remember to check the credential itself.
|
|
26
|
+
*/
|
|
27
|
+
export declare class CredentialWaitController {
|
|
28
|
+
private readonly deps;
|
|
29
|
+
private readonly log;
|
|
30
|
+
constructor(deps: CredentialWaitControllerDeps);
|
|
31
|
+
/**
|
|
32
|
+
* Run one engine call that may dispatch a step, parking the run when the dispatch's lease was
|
|
33
|
+
* refused. Anything else (a result or a throw) passes through untouched.
|
|
34
|
+
*/
|
|
35
|
+
guard(workspaceId: string, executionId: string, work: () => Promise<AdvanceResult>): Promise<AdvanceResult>;
|
|
36
|
+
/**
|
|
37
|
+
* Park the run's current step on a credential wait. Answers `null` when the run is no longer
|
|
38
|
+
* live (stopped or settled while the dispatch was failing), so the caller keeps the original
|
|
39
|
+
* outcome rather than parking a run nobody is driving.
|
|
40
|
+
*/
|
|
41
|
+
private park;
|
|
42
|
+
/**
|
|
43
|
+
* Resume a step parked on a lapsed credential: re-mint the activation through `renew`, clear the
|
|
44
|
+
* park and wake the driver, which re-dispatches the SAME step. The park and the caller are
|
|
45
|
+
* checked before `renew` runs, so a run that is not parked (already resumed, stopped) never gets
|
|
46
|
+
* a fresh credential minted for it, and nobody but the initiator mints one the lease would not
|
|
47
|
+
* read.
|
|
48
|
+
*/
|
|
49
|
+
resume(workspaceId: string, executionId: string, actorUserId: string | null, renew: () => Promise<void>): Promise<ExecutionInstance>;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=CredentialWaitController.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CredentialWaitController.d.ts","sourceRoot":"","sources":["../../../src/modules/execution/CredentialWaitController.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,EACL,iBAAiB,EACjB,mBAAmB,EACnB,MAAM,EACN,UAAU,EACX,MAAM,qBAAqB,CAAA;AAU5B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AA6C/C,MAAM,WAAW,4BAA4B;IAC3C,YAAY,EAAE,eAAe,CAAA;IAC7B,SAAS,EAAE,SAAS,CAAA;IACpB,mBAAmB,EAAE,mBAAmB,CAAA;IACxC,KAAK,EAAE,KAAK,CAAA;IACZ,UAAU,EAAE,UAAU,CAAA;IACtB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,wBAAwB;IAGvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFjC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAE5B,YAA6B,IAAI,EAAE,4BAA4B,EAE9D;IAED;;;OAGG;IACG,KAAK,CACT,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,OAAO,CAAC,aAAa,CAAC,GACjC,OAAO,CAAC,aAAa,CAAC,CAYxB;IAED;;;;OAIG;YACW,IAAI;IA6BlB;;;;;;OAMG;IACG,MAAM,CACV,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GACzB,OAAO,CAAC,iBAAiB,CAAC,CAiC5B;CACF"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { isCredentialWaitParked, mayResumeCredentialWait } from '@cat-factory/contracts';
|
|
2
|
+
import { ConflictError, CredentialRequiredError, ForbiddenError, assertFound, getErrorReason, noopLogger, } from '@cat-factory/kernel';
|
|
3
|
+
/**
|
|
4
|
+
* The `details.reason` a lease refusal carries. Every dispatch that runs on a personal
|
|
5
|
+
* subscription leases the run's activation, and the lease is the one authority on whether that
|
|
6
|
+
* activation is still live, so this reason is what the park keys on rather than a prediction of
|
|
7
|
+
* which steps will need a credential.
|
|
8
|
+
*/
|
|
9
|
+
const LAPSED_REASON = 'password_required';
|
|
10
|
+
/** Whether a thrown error is a step's lease being refused for a lapsed credential. */
|
|
11
|
+
function isLapseError(error) {
|
|
12
|
+
return error instanceof CredentialRequiredError && getErrorReason(error) === LAPSED_REASON;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Whether a settled step result is the same refusal, after an async dispatch site classified the
|
|
16
|
+
* throw into a `preflight` failure (see `classifyDispatchFailure`).
|
|
17
|
+
*/
|
|
18
|
+
function isLapseResult(result) {
|
|
19
|
+
return (result.kind === 'job_failed' &&
|
|
20
|
+
result.failureKind === 'preflight' &&
|
|
21
|
+
result.reason === LAPSED_REASON);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The approval id of a LIVE credential park, or null. Only a `blocked` run counts: a run stopped
|
|
25
|
+
* while parked keeps the step exactly as it stood, and resuming it would re-mint a credential for
|
|
26
|
+
* a run nobody is driving.
|
|
27
|
+
*/
|
|
28
|
+
function parkedApprovalId(instance) {
|
|
29
|
+
const step = instance.steps[instance.currentStep];
|
|
30
|
+
if (instance.status !== 'blocked' || !step || !isCredentialWaitParked(step))
|
|
31
|
+
return null;
|
|
32
|
+
return step.approval.id;
|
|
33
|
+
}
|
|
34
|
+
function notParked() {
|
|
35
|
+
return new ConflictError('This run is not waiting on a personal subscription credential.', 'credential_wait_not_parked');
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Parks a run whose personal-subscription credential lapsed, and resumes it.
|
|
39
|
+
*
|
|
40
|
+
* A run on an individual-usage model leases its initiator's credential at every dispatch, from an
|
|
41
|
+
* activation with a fixed lifetime. Whatever advanced the run to that dispatch (a human answering
|
|
42
|
+
* a review, a background re-review converging, a timer) is irrelevant here: the lease is refused,
|
|
43
|
+
* and the step parks on the generic approval with `credentialWait` set, instead of failing the run.
|
|
44
|
+
* The person answers it with {@link resume}, which re-mints the activation from their personal
|
|
45
|
+
* password before re-dispatching.
|
|
46
|
+
*
|
|
47
|
+
* {@link guard} is the ONE place the refusal is recognised. The engine routes every call that can
|
|
48
|
+
* dispatch (advance and the three poll entry points) through it, so no dispatch site and no
|
|
49
|
+
* run-advancing route has to remember to check the credential itself.
|
|
50
|
+
*/
|
|
51
|
+
export class CredentialWaitController {
|
|
52
|
+
deps;
|
|
53
|
+
log;
|
|
54
|
+
constructor(deps) {
|
|
55
|
+
this.deps = deps;
|
|
56
|
+
this.log = deps.logger ?? noopLogger;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Run one engine call that may dispatch a step, parking the run when the dispatch's lease was
|
|
60
|
+
* refused. Anything else (a result or a throw) passes through untouched.
|
|
61
|
+
*/
|
|
62
|
+
async guard(workspaceId, executionId, work) {
|
|
63
|
+
let result;
|
|
64
|
+
try {
|
|
65
|
+
result = await work();
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
if (!isLapseError(error))
|
|
69
|
+
throw error;
|
|
70
|
+
const parked = await this.park(workspaceId, executionId);
|
|
71
|
+
if (!parked)
|
|
72
|
+
throw error;
|
|
73
|
+
return parked;
|
|
74
|
+
}
|
|
75
|
+
if (!isLapseResult(result))
|
|
76
|
+
return result;
|
|
77
|
+
return (await this.park(workspaceId, executionId)) ?? result;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Park the run's current step on a credential wait. Answers `null` when the run is no longer
|
|
81
|
+
* live (stopped or settled while the dispatch was failing), so the caller keeps the original
|
|
82
|
+
* outcome rather than parking a run nobody is driving.
|
|
83
|
+
*/
|
|
84
|
+
async park(workspaceId, executionId) {
|
|
85
|
+
let decisionId = null;
|
|
86
|
+
const instance = await this.deps.stateMachine.mutateInstance(workspaceId, executionId, (inst) => {
|
|
87
|
+
decisionId = null;
|
|
88
|
+
const step = inst.steps[inst.currentStep];
|
|
89
|
+
if (!step || (inst.status !== 'running' && inst.status !== 'paused'))
|
|
90
|
+
return;
|
|
91
|
+
step.credentialWait = { raisedAt: this.deps.clock.now() };
|
|
92
|
+
decisionId = this.deps.stateMachine.openDecisionPark(step, "The run's personal subscription credential lapsed.");
|
|
93
|
+
inst.status = 'blocked';
|
|
94
|
+
});
|
|
95
|
+
if (!decisionId)
|
|
96
|
+
return null;
|
|
97
|
+
await this.deps.stateMachine.updateBlockProgress(workspaceId, instance, 'blocked');
|
|
98
|
+
this.log.info('run parked: personal subscription credential lapsed', {
|
|
99
|
+
workspaceId,
|
|
100
|
+
runId: executionId,
|
|
101
|
+
stepIndex: instance.currentStep,
|
|
102
|
+
});
|
|
103
|
+
await this.deps.stateMachine.emitInstance(workspaceId, instance);
|
|
104
|
+
await this.deps.stateMachine.ensureWaitingNotification(workspaceId, instance);
|
|
105
|
+
return { kind: 'awaiting_decision', decisionId };
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Resume a step parked on a lapsed credential: re-mint the activation through `renew`, clear the
|
|
109
|
+
* park and wake the driver, which re-dispatches the SAME step. The park and the caller are
|
|
110
|
+
* checked before `renew` runs, so a run that is not parked (already resumed, stopped) never gets
|
|
111
|
+
* a fresh credential minted for it, and nobody but the initiator mints one the lease would not
|
|
112
|
+
* read.
|
|
113
|
+
*/
|
|
114
|
+
async resume(workspaceId, executionId, actorUserId, renew) {
|
|
115
|
+
const current = assertFound(await this.deps.executionRepository.get(workspaceId, executionId), 'Execution', executionId);
|
|
116
|
+
if (!parkedApprovalId(current))
|
|
117
|
+
throw notParked();
|
|
118
|
+
if (!mayResumeCredentialWait(current.initiatedBy, actorUserId)) {
|
|
119
|
+
throw new ForbiddenError('Only the person who started this run can renew its personal subscription credential.', { reason: 'credential_wait_not_initiator' });
|
|
120
|
+
}
|
|
121
|
+
await renew();
|
|
122
|
+
let approvalId = '';
|
|
123
|
+
const instance = await this.deps.stateMachine.mutateInstance(workspaceId, executionId, (inst) => {
|
|
124
|
+
const parked = parkedApprovalId(inst);
|
|
125
|
+
if (!parked)
|
|
126
|
+
throw notParked();
|
|
127
|
+
approvalId = parked;
|
|
128
|
+
const step = inst.steps[inst.currentStep];
|
|
129
|
+
step.credentialWait = null;
|
|
130
|
+
step.approval = null;
|
|
131
|
+
this.deps.stepGraph.startStep(step);
|
|
132
|
+
inst.status = 'running';
|
|
133
|
+
});
|
|
134
|
+
await this.deps.stateMachine.updateBlockProgress(workspaceId, instance, 'in_progress');
|
|
135
|
+
await this.deps.stateMachine.emitInstance(workspaceId, instance);
|
|
136
|
+
await this.deps.workRunner.signalDecision(workspaceId, instance.id, approvalId, 'approved');
|
|
137
|
+
return instance;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=CredentialWaitController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CredentialWaitController.js","sourceRoot":"","sources":["../../../src/modules/execution/CredentialWaitController.ts"],"names":[],"mappings":"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"}
|