feat: harden orchestrator execution runtime
This commit is contained in:
@@ -47,11 +47,8 @@ function disabledHandoffError(decision) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Phase 3 boundary adapter.
|
||||
*
|
||||
* It turns control-plane routing into a framework-neutral, auditable decision.
|
||||
* It intentionally has no remote dispatch path yet: Native remains owned by the
|
||||
* existing Portal Agent Run and non-Native candidates are dry-run only.
|
||||
* Framework-neutral control-plane adapter. Routing, authorization and the
|
||||
* environment/admin gates are evaluated before a remote engine can be invoked.
|
||||
*/
|
||||
export function createWorkflowExecutionAdapter({
|
||||
configService,
|
||||
@@ -74,27 +71,32 @@ export function createWorkflowExecutionAdapter({
|
||||
});
|
||||
const candidateEngine = selection.candidateEngine ?? selection.engine ?? WORKFLOW_ENGINE.NATIVE;
|
||||
const nonNativeCandidate = candidateEngine !== WORKFLOW_ENGINE.NATIVE;
|
||||
const selectedEngine = selection.engine ?? WORKFLOW_ENGINE.NATIVE;
|
||||
const nonNativeSelected = selectedEngine !== WORKFLOW_ENGINE.NATIVE;
|
||||
const gates = {
|
||||
implementation: false,
|
||||
routingSelected: nonNativeCandidate,
|
||||
engineRegistered: engineRegistry.has(candidateEngine),
|
||||
implementation: true,
|
||||
routingSelected: nonNativeSelected,
|
||||
engineRegistered: engineRegistry.has(selectedEngine),
|
||||
idempotencyKeyPresent: Boolean(request.idempotencyKey),
|
||||
executionAuthorized: request.authorization.executionAllowed,
|
||||
killSwitchOpen: selection.reason !== 'kill_switch',
|
||||
};
|
||||
const handoffAllowed = nonNativeSelected && Object.values(gates).every(Boolean);
|
||||
return {
|
||||
version: EXECUTION_DECISION_VERSION,
|
||||
runId: request.spec.runId,
|
||||
requestId: request.spec.requestId,
|
||||
mode: selection.mode,
|
||||
candidateEngine,
|
||||
effectiveEngine: WORKFLOW_ENGINE.NATIVE,
|
||||
effectiveEngine: handoffAllowed ? selectedEngine : WORKFLOW_ENGINE.NATIVE,
|
||||
fallbackEngine: selection.fallbackEngine ?? WORKFLOW_ENGINE.NATIVE,
|
||||
dryRun: nonNativeCandidate,
|
||||
handoffAllowed: false,
|
||||
reason: nonNativeCandidate
|
||||
? 'execution_gate_disabled'
|
||||
: selection.reason ?? 'native_selected',
|
||||
dryRun: nonNativeCandidate && !handoffAllowed,
|
||||
handoffAllowed,
|
||||
reason: handoffAllowed
|
||||
? selection.reason ?? 'execution_handoff_selected'
|
||||
: nonNativeCandidate
|
||||
? selection.reason ?? 'execution_gate_disabled'
|
||||
: selection.reason ?? 'native_selected',
|
||||
candidateReason: selection.candidateReason ?? null,
|
||||
configVersion: selection.configVersion,
|
||||
gates,
|
||||
@@ -106,29 +108,55 @@ export function createWorkflowExecutionAdapter({
|
||||
plan,
|
||||
|
||||
async start(input) {
|
||||
const request = normalizeWorkflowExecutionRequest(input);
|
||||
const decision = await plan(input);
|
||||
if (decision.candidateEngine === WORKFLOW_ENGINE.NATIVE) {
|
||||
if (!decision.handoffAllowed) {
|
||||
if (decision.candidateEngine !== WORKFLOW_ENGINE.NATIVE) {
|
||||
throw disabledHandoffError(decision);
|
||||
}
|
||||
return {
|
||||
dispatched: false,
|
||||
reason: 'native_execution_owned_by_portal',
|
||||
decision,
|
||||
};
|
||||
}
|
||||
throw disabledHandoffError(decision);
|
||||
const engine = engineRegistry.get(decision.effectiveEngine);
|
||||
try {
|
||||
const state = await engine.start(request.spec);
|
||||
return {
|
||||
dispatched: true,
|
||||
engine: decision.effectiveEngine,
|
||||
state,
|
||||
decision,
|
||||
};
|
||||
} catch (error) {
|
||||
error.code = error.code ?? 'WORKFLOW_EXECUTION_HANDOFF_FAILED';
|
||||
error.decision = decision;
|
||||
error.fallbackRequested = request.controls.fallbackAllowed;
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
|
||||
async resume() {
|
||||
throw disabledHandoffError({
|
||||
effectiveEngine: WORKFLOW_ENGINE.NATIVE,
|
||||
reason: 'execution_gate_disabled',
|
||||
});
|
||||
async resume({ engineId = WORKFLOW_ENGINE.LANGGRAPH, runId, input = null } = {}) {
|
||||
const engine = engineRegistry.get(engineId);
|
||||
if (!engine || engineId === WORKFLOW_ENGINE.NATIVE) {
|
||||
throw disabledHandoffError({
|
||||
effectiveEngine: WORKFLOW_ENGINE.NATIVE,
|
||||
reason: 'execution_gate_disabled',
|
||||
});
|
||||
}
|
||||
return engine.resume(runId, input);
|
||||
},
|
||||
|
||||
async cancel() {
|
||||
throw disabledHandoffError({
|
||||
effectiveEngine: WORKFLOW_ENGINE.NATIVE,
|
||||
reason: 'execution_gate_disabled',
|
||||
});
|
||||
async cancel({ engineId = WORKFLOW_ENGINE.LANGGRAPH, runId, reason = null } = {}) {
|
||||
const engine = engineRegistry.get(engineId);
|
||||
if (!engine || engineId === WORKFLOW_ENGINE.NATIVE) {
|
||||
throw disabledHandoffError({
|
||||
effectiveEngine: WORKFLOW_ENGINE.NATIVE,
|
||||
reason: 'execution_gate_disabled',
|
||||
});
|
||||
}
|
||||
return engine.cancel(runId, reason);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user