nexus-agents 2.125.25 → 2.125.26
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/{chunk-F6VJEXXJ.js → chunk-2SCNPVUP.js} +229 -144
- package/dist/{chunk-F6VJEXXJ.js.map → chunk-2SCNPVUP.js.map} +1 -1
- package/dist/{chunk-B3TJNOKQ.js → chunk-KEQQQRA6.js} +3 -3
- package/dist/{chunk-YQARWBVL.js → chunk-WX4OJ4GY.js} +2 -2
- package/dist/cli.js +3 -3
- package/dist/index.d.ts +146 -107
- package/dist/index.js +2 -2
- package/dist/{setup-command-PRTMR4DK.js → setup-command-Z5A7CFDT.js} +3 -3
- package/package.json +1 -1
- /package/dist/{chunk-B3TJNOKQ.js.map → chunk-KEQQQRA6.js.map} +0 -0
- /package/dist/{chunk-YQARWBVL.js.map → chunk-WX4OJ4GY.js.map} +0 -0
- /package/dist/{setup-command-PRTMR4DK.js.map → setup-command-Z5A7CFDT.js.map} +0 -0
|
@@ -123,7 +123,7 @@ import {
|
|
|
123
123
|
DEFAULT_TASK_TTL_MS,
|
|
124
124
|
DEFAULT_TOOL_RATE_LIMITS,
|
|
125
125
|
clampTaskTtl
|
|
126
|
-
} from "./chunk-
|
|
126
|
+
} from "./chunk-KEQQQRA6.js";
|
|
127
127
|
import {
|
|
128
128
|
resolveInsideRoot
|
|
129
129
|
} from "./chunk-NUBSJGQZ.js";
|
|
@@ -26260,6 +26260,9 @@ async function runSinglePrecondition(config, ctx, options) {
|
|
|
26260
26260
|
|
|
26261
26261
|
// src/orchestration/graph/graph-executor.ts
|
|
26262
26262
|
var logger16 = createLogger({ component: "GraphExecutor" });
|
|
26263
|
+
function isPolicyBlockedError(error) {
|
|
26264
|
+
return error instanceof Error && error.name === "PolicyBlockedError";
|
|
26265
|
+
}
|
|
26263
26266
|
function failureClassification(category) {
|
|
26264
26267
|
return { errorCategory: category, isRetryable: defaultRetryable(category) };
|
|
26265
26268
|
}
|
|
@@ -26639,6 +26642,30 @@ async function executeWithVerification(args) {
|
|
|
26639
26642
|
...gotoTarget !== void 0 ? { gotoTarget } : {}
|
|
26640
26643
|
};
|
|
26641
26644
|
}
|
|
26645
|
+
function failedNodeResult(nodeId, error, startTime) {
|
|
26646
|
+
const message = getErrorMessage(error);
|
|
26647
|
+
logger16.warn("Node execution failed", { nodeId, error: message });
|
|
26648
|
+
if (isPolicyBlockedError(error)) {
|
|
26649
|
+
return {
|
|
26650
|
+
nodeId,
|
|
26651
|
+
stateUpdates: {},
|
|
26652
|
+
durationMs: getTimeProvider().now() - startTime,
|
|
26653
|
+
status: "failed",
|
|
26654
|
+
error: message,
|
|
26655
|
+
policyBlocked: true,
|
|
26656
|
+
...failureClassification("permission")
|
|
26657
|
+
};
|
|
26658
|
+
}
|
|
26659
|
+
const category = coarsenFailureCategory(categorizeOutcomeError(error));
|
|
26660
|
+
return {
|
|
26661
|
+
nodeId,
|
|
26662
|
+
stateUpdates: {},
|
|
26663
|
+
durationMs: getTimeProvider().now() - startTime,
|
|
26664
|
+
status: "failed",
|
|
26665
|
+
error: message,
|
|
26666
|
+
...failureClassification(category)
|
|
26667
|
+
};
|
|
26668
|
+
}
|
|
26642
26669
|
async function executeSingleNode(graph, nodeId, state, nodeCtx, options) {
|
|
26643
26670
|
const prior = options?.priorResults?.get(nodeId);
|
|
26644
26671
|
if (prior?.status === "success") {
|
|
@@ -26665,17 +26692,7 @@ async function executeSingleNode(graph, nodeId, state, nodeCtx, options) {
|
|
|
26665
26692
|
try {
|
|
26666
26693
|
return await executeWithVerification({ node, nodeId, state, startTime, nodeCtx, options });
|
|
26667
26694
|
} catch (error) {
|
|
26668
|
-
|
|
26669
|
-
logger16.warn("Node execution failed", { nodeId, error: message });
|
|
26670
|
-
const category = coarsenFailureCategory(categorizeOutcomeError(error));
|
|
26671
|
-
return {
|
|
26672
|
-
nodeId,
|
|
26673
|
-
stateUpdates: {},
|
|
26674
|
-
durationMs: getTimeProvider().now() - startTime,
|
|
26675
|
-
status: "failed",
|
|
26676
|
-
error: message,
|
|
26677
|
-
...failureClassification(category)
|
|
26678
|
-
};
|
|
26695
|
+
return failedNodeResult(nodeId, error, startTime);
|
|
26679
26696
|
}
|
|
26680
26697
|
}
|
|
26681
26698
|
function resolveEntryNodes(graph, state) {
|
|
@@ -26968,6 +26985,149 @@ function customReducer(defaultValue, merge) {
|
|
|
26968
26985
|
return { defaultValue, reducer: { type: "custom", merge } };
|
|
26969
26986
|
}
|
|
26970
26987
|
|
|
26988
|
+
// src/pipeline/v2-config.ts
|
|
26989
|
+
function readV2Mode() {
|
|
26990
|
+
const env = process.env["NEXUS_V2_MODE"];
|
|
26991
|
+
if (env === "off" || env === "partial") return env;
|
|
26992
|
+
return "full";
|
|
26993
|
+
}
|
|
26994
|
+
function resolveFlag(envKey, umbrellaDefault) {
|
|
26995
|
+
const env = process.env[envKey];
|
|
26996
|
+
if (env === "true") return true;
|
|
26997
|
+
if (env === "false") return false;
|
|
26998
|
+
return umbrellaDefault;
|
|
26999
|
+
}
|
|
27000
|
+
function resolvePolicyMode(umbrella) {
|
|
27001
|
+
const env = process.env["NEXUS_V2_POLICY_MODE"];
|
|
27002
|
+
if (env === "off" || env === "warn" || env === "block") return env;
|
|
27003
|
+
if (umbrella === "off") return "off";
|
|
27004
|
+
if (umbrella === "partial") return "warn";
|
|
27005
|
+
return "block";
|
|
27006
|
+
}
|
|
27007
|
+
function resolveV2Config() {
|
|
27008
|
+
const mode = readV2Mode();
|
|
27009
|
+
const umbrellaDelegate = mode !== "off";
|
|
27010
|
+
const umbrellaOrchestrate = mode === "full";
|
|
27011
|
+
return {
|
|
27012
|
+
mode,
|
|
27013
|
+
delegateEnabled: resolveFlag("NEXUS_V2_DELEGATE", umbrellaDelegate),
|
|
27014
|
+
orchestrateEnabled: resolveFlag("NEXUS_V2_ORCHESTRATE", umbrellaOrchestrate),
|
|
27015
|
+
policyMode: resolvePolicyMode(mode),
|
|
27016
|
+
aorchestraEnabled: resolveFlag("NEXUS_AORCHESTRA", true),
|
|
27017
|
+
dispatchEnabled: resolveFlag("NEXUS_AORCHESTRA_DISPATCH", true)
|
|
27018
|
+
};
|
|
27019
|
+
}
|
|
27020
|
+
|
|
27021
|
+
// src/pipeline/policy-evaluator.ts
|
|
27022
|
+
var logger17 = createLogger({ component: "PolicyEvaluator" });
|
|
27023
|
+
var PolicyBlockedError = class extends Error {
|
|
27024
|
+
gateId;
|
|
27025
|
+
violations;
|
|
27026
|
+
constructor(gateId, violations) {
|
|
27027
|
+
const summary = violations.map((v) => v.ruleId).join(", ");
|
|
27028
|
+
super(`Policy gate '${gateId}' blocked stage boundary (rules: ${summary || "none"})`);
|
|
27029
|
+
this.name = "PolicyBlockedError";
|
|
27030
|
+
this.gateId = gateId;
|
|
27031
|
+
this.violations = violations;
|
|
27032
|
+
}
|
|
27033
|
+
};
|
|
27034
|
+
function getGateEnforcementMode() {
|
|
27035
|
+
const env = process.env["NEXUS_POLICY_GATE_MODE"];
|
|
27036
|
+
if (env === "off" || env === "warn" || env === "block") return env;
|
|
27037
|
+
return "warn";
|
|
27038
|
+
}
|
|
27039
|
+
function enforceGatePolicy(enforcement, target) {
|
|
27040
|
+
const mode = enforcement.mode ?? getGateEnforcementMode();
|
|
27041
|
+
const result = evaluatePipelinePolicy(
|
|
27042
|
+
{
|
|
27043
|
+
engine: enforcement.engine,
|
|
27044
|
+
mode,
|
|
27045
|
+
...enforcement.eventBus !== void 0 ? { eventBus: enforcement.eventBus } : {}
|
|
27046
|
+
},
|
|
27047
|
+
{
|
|
27048
|
+
taskId: target.taskId,
|
|
27049
|
+
stageId: target.gateId,
|
|
27050
|
+
stageType: target.stageType,
|
|
27051
|
+
pipelineState: enforcement.pipelineState
|
|
27052
|
+
}
|
|
27053
|
+
);
|
|
27054
|
+
if (mode === "block" && !result.allowed) {
|
|
27055
|
+
throw new PolicyBlockedError(target.gateId, result.violations);
|
|
27056
|
+
}
|
|
27057
|
+
return result;
|
|
27058
|
+
}
|
|
27059
|
+
function getPolicyMode() {
|
|
27060
|
+
return resolveV2Config().policyMode;
|
|
27061
|
+
}
|
|
27062
|
+
function evaluatePipelinePolicy(options, context) {
|
|
27063
|
+
const mode = options.mode ?? getPolicyMode();
|
|
27064
|
+
if (mode === "off") {
|
|
27065
|
+
return { allowed: true, violations: [], mode };
|
|
27066
|
+
}
|
|
27067
|
+
const violations = [];
|
|
27068
|
+
const rules = options.engine.listRules();
|
|
27069
|
+
for (const rule of rules) {
|
|
27070
|
+
let decision;
|
|
27071
|
+
try {
|
|
27072
|
+
decision = rule.evaluate(context);
|
|
27073
|
+
} catch (err2) {
|
|
27074
|
+
const error = err2 instanceof Error ? err2 : new Error(String(err2));
|
|
27075
|
+
logger17.error("Policy rule threw during evaluation", error, {
|
|
27076
|
+
ruleId: rule.id,
|
|
27077
|
+
stageId: context.stageId
|
|
27078
|
+
});
|
|
27079
|
+
const message = error.message;
|
|
27080
|
+
violations.push({
|
|
27081
|
+
ruleId: rule.id,
|
|
27082
|
+
reason: `Rule threw during evaluation: ${message}`
|
|
27083
|
+
});
|
|
27084
|
+
continue;
|
|
27085
|
+
}
|
|
27086
|
+
if (!decision.allow) {
|
|
27087
|
+
violations.push({
|
|
27088
|
+
ruleId: rule.id,
|
|
27089
|
+
reason: decision.reason,
|
|
27090
|
+
...decision.escalateTo !== void 0 ? { escalateTo: decision.escalateTo } : {}
|
|
27091
|
+
});
|
|
27092
|
+
}
|
|
27093
|
+
}
|
|
27094
|
+
if (violations.length > 0) {
|
|
27095
|
+
emitPolicyEvents(options.eventBus, context, violations);
|
|
27096
|
+
logViolations(context, violations, mode);
|
|
27097
|
+
}
|
|
27098
|
+
const allowed = mode === "warn" || violations.length === 0;
|
|
27099
|
+
return { allowed, violations, mode };
|
|
27100
|
+
}
|
|
27101
|
+
function emitPolicyEvents(eventBus, context, violations) {
|
|
27102
|
+
if (eventBus === void 0) return;
|
|
27103
|
+
for (const v of violations) {
|
|
27104
|
+
const event = {
|
|
27105
|
+
type: "policy.evaluated",
|
|
27106
|
+
timestamp: Date.now(),
|
|
27107
|
+
executionId: context.taskId,
|
|
27108
|
+
gateId: `${context.stageId}:${v.ruleId}`,
|
|
27109
|
+
decision: "deny"
|
|
27110
|
+
};
|
|
27111
|
+
eventBus.emit(event);
|
|
27112
|
+
}
|
|
27113
|
+
}
|
|
27114
|
+
function logViolations(context, violations, mode) {
|
|
27115
|
+
const summary = violations.map((v) => v.ruleId).join(", ");
|
|
27116
|
+
if (mode === "block") {
|
|
27117
|
+
logger17.warn("Policy BLOCKED stage", {
|
|
27118
|
+
stageId: context.stageId,
|
|
27119
|
+
violations: summary,
|
|
27120
|
+
count: violations.length
|
|
27121
|
+
});
|
|
27122
|
+
} else {
|
|
27123
|
+
logger17.info("Policy WARN (violations logged)", {
|
|
27124
|
+
stageId: context.stageId,
|
|
27125
|
+
violations: summary,
|
|
27126
|
+
count: violations.length
|
|
27127
|
+
});
|
|
27128
|
+
}
|
|
27129
|
+
}
|
|
27130
|
+
|
|
26971
27131
|
// src/pipeline/plan-compiler.ts
|
|
26972
27132
|
function compilePlan(plan, options) {
|
|
26973
27133
|
if (plan.stages.length === 0) {
|
|
@@ -26987,7 +27147,7 @@ function compilePlan(plan, options) {
|
|
|
26987
27147
|
const builder = new GraphBuilder();
|
|
26988
27148
|
addPipelineState(builder);
|
|
26989
27149
|
addStageNodes(builder, plan.stages, options?.pluginRegistry);
|
|
26990
|
-
addGateNodes(builder, plan.policyGates);
|
|
27150
|
+
addGateNodes(builder, plan.policyGates, plan, options?.policyEnforcement);
|
|
26991
27151
|
addEdges(builder, plan.stages, plan.policyGates);
|
|
26992
27152
|
const result = builder.compile();
|
|
26993
27153
|
if (result.ok) {
|
|
@@ -27020,20 +27180,32 @@ function createStageHandler(stage, registry) {
|
|
|
27020
27180
|
stageResults: [{ stageId: stage.id, status: "completed" }]
|
|
27021
27181
|
});
|
|
27022
27182
|
}
|
|
27023
|
-
function createGateHandler(gate) {
|
|
27024
|
-
|
|
27025
|
-
|
|
27026
|
-
|
|
27027
|
-
|
|
27183
|
+
function createGateHandler(gate, taskId, stageType, enforcement) {
|
|
27184
|
+
if (enforcement === void 0) {
|
|
27185
|
+
return (_state) => Promise.resolve({
|
|
27186
|
+
currentStage: gate.id,
|
|
27187
|
+
stageResults: [{ gateId: gate.id, status: "passed" }]
|
|
27188
|
+
});
|
|
27189
|
+
}
|
|
27190
|
+
return (_state) => {
|
|
27191
|
+
const verdict = enforceGatePolicy(enforcement, { gateId: gate.id, taskId, stageType });
|
|
27192
|
+
const status = verdict.allowed ? "passed" : "warned";
|
|
27193
|
+
return Promise.resolve({
|
|
27194
|
+
currentStage: gate.id,
|
|
27195
|
+
stageResults: [{ gateId: gate.id, status }]
|
|
27196
|
+
});
|
|
27197
|
+
};
|
|
27028
27198
|
}
|
|
27029
27199
|
function addStageNodes(builder, stages, registry) {
|
|
27030
27200
|
for (const stage of stages) {
|
|
27031
27201
|
builder.addNode(stage.id, createStageHandler(stage, registry));
|
|
27032
27202
|
}
|
|
27033
27203
|
}
|
|
27034
|
-
function addGateNodes(builder, gates) {
|
|
27204
|
+
function addGateNodes(builder, gates, plan, enforcement) {
|
|
27205
|
+
const stageTypeById = new Map(plan.stages.map((s) => [s.id, s.type]));
|
|
27035
27206
|
for (const gate of gates) {
|
|
27036
|
-
|
|
27207
|
+
const stageType = stageTypeById.get(gate.beforeStage) ?? "gate";
|
|
27208
|
+
builder.addNode(gate.id, createGateHandler(gate, plan.taskId, stageType, enforcement));
|
|
27037
27209
|
}
|
|
27038
27210
|
}
|
|
27039
27211
|
function addEdges(builder, stages, gates) {
|
|
@@ -27201,7 +27373,7 @@ var StageResultSchema = z48.object({
|
|
|
27201
27373
|
});
|
|
27202
27374
|
|
|
27203
27375
|
// src/pipeline/plugin-registry.ts
|
|
27204
|
-
var
|
|
27376
|
+
var logger18 = createLogger({ component: "PluginRegistry" });
|
|
27205
27377
|
var PluginRegistry = class {
|
|
27206
27378
|
plugins = /* @__PURE__ */ new Map();
|
|
27207
27379
|
options;
|
|
@@ -27233,7 +27405,7 @@ var PluginRegistry = class {
|
|
|
27233
27405
|
};
|
|
27234
27406
|
}
|
|
27235
27407
|
this.plugins.set(plugin.manifest.id, plugin);
|
|
27236
|
-
|
|
27408
|
+
logger18.info("Plugin registered", {
|
|
27237
27409
|
id: plugin.manifest.id,
|
|
27238
27410
|
version: plugin.manifest.version,
|
|
27239
27411
|
trustLevel: plugin.manifest.trustLevel
|
|
@@ -27251,7 +27423,7 @@ var PluginRegistry = class {
|
|
|
27251
27423
|
}
|
|
27252
27424
|
freeze() {
|
|
27253
27425
|
this.isFrozen = true;
|
|
27254
|
-
|
|
27426
|
+
logger18.info("Plugin registry frozen", {
|
|
27255
27427
|
pluginCount: this.plugins.size
|
|
27256
27428
|
});
|
|
27257
27429
|
}
|
|
@@ -27306,7 +27478,7 @@ var PluginRegistry = class {
|
|
|
27306
27478
|
};
|
|
27307
27479
|
|
|
27308
27480
|
// src/pipeline/core-plugins.ts
|
|
27309
|
-
var
|
|
27481
|
+
var logger19 = createLogger({ component: "CorePlugins" });
|
|
27310
27482
|
function noopStageResult() {
|
|
27311
27483
|
return { success: true, outputArtifacts: [], metadata: { stub: true } };
|
|
27312
27484
|
}
|
|
@@ -27359,11 +27531,11 @@ function registerCorePlugins(registry) {
|
|
|
27359
27531
|
} else {
|
|
27360
27532
|
const msg = `Failed to register ${plugin.manifest.id}: ${JSON.stringify(result.error)}`;
|
|
27361
27533
|
errors.push(msg);
|
|
27362
|
-
|
|
27534
|
+
logger19.warn(msg);
|
|
27363
27535
|
}
|
|
27364
27536
|
}
|
|
27365
27537
|
reg.freeze();
|
|
27366
|
-
|
|
27538
|
+
logger19.info("Core plugins registered", { registered, failed: errors.length });
|
|
27367
27539
|
return { registered, failed: errors.length, errors };
|
|
27368
27540
|
}
|
|
27369
27541
|
function createCorePluginRegistry() {
|
|
@@ -27463,7 +27635,7 @@ function emitPipelineStageEvent(prefix, stage, status, details) {
|
|
|
27463
27635
|
// src/pipeline/trace-writer.ts
|
|
27464
27636
|
import { mkdir, writeFile, rename, unlink } from "fs/promises";
|
|
27465
27637
|
import { join as join4 } from "path";
|
|
27466
|
-
var
|
|
27638
|
+
var logger20 = createLogger({ component: "TraceWriter" });
|
|
27467
27639
|
var MAX_BUFFER_SIZE = 5e4;
|
|
27468
27640
|
var TraceWriter = class {
|
|
27469
27641
|
constructor(bus, options) {
|
|
@@ -27497,7 +27669,7 @@ var TraceWriter = class {
|
|
|
27497
27669
|
} catch (err2) {
|
|
27498
27670
|
await unlink(traceTmp).catch((unlinkErr) => {
|
|
27499
27671
|
const msg = unlinkErr instanceof Error ? unlinkErr.message : String(unlinkErr);
|
|
27500
|
-
|
|
27672
|
+
logger20.warn("Failed to clean up trace temp file", { path: traceTmp, error: msg });
|
|
27501
27673
|
});
|
|
27502
27674
|
throw err2;
|
|
27503
27675
|
}
|
|
@@ -27510,11 +27682,11 @@ var TraceWriter = class {
|
|
|
27510
27682
|
} catch (err2) {
|
|
27511
27683
|
await unlink(indexTmp).catch((unlinkErr) => {
|
|
27512
27684
|
const msg = unlinkErr instanceof Error ? unlinkErr.message : String(unlinkErr);
|
|
27513
|
-
|
|
27685
|
+
logger20.warn("Failed to clean up index temp file", { path: indexTmp, error: msg });
|
|
27514
27686
|
});
|
|
27515
27687
|
throw err2;
|
|
27516
27688
|
}
|
|
27517
|
-
|
|
27689
|
+
logger20.info("Trace flushed", {
|
|
27518
27690
|
runId: this.options.runId,
|
|
27519
27691
|
events: this.buffer.length
|
|
27520
27692
|
});
|
|
@@ -27630,7 +27802,12 @@ var PipelineRunner = class {
|
|
|
27630
27802
|
/** Compiles a PlanContract into a CompiledPipeline. */
|
|
27631
27803
|
compile(plan, options) {
|
|
27632
27804
|
const { pluginRegistry } = resolvePipelineDeps(options);
|
|
27633
|
-
const compileOpts = {
|
|
27805
|
+
const compileOpts = {
|
|
27806
|
+
pluginRegistry,
|
|
27807
|
+
// Thread stage-boundary policy enforcement through to the gate handlers
|
|
27808
|
+
// (#3177). Unset → gates remain no-op passes (back-compat).
|
|
27809
|
+
...options?.policyEnforcement !== void 0 ? { policyEnforcement: options.policyEnforcement } : {}
|
|
27810
|
+
};
|
|
27634
27811
|
const graphResult = compilePlan(plan, compileOpts);
|
|
27635
27812
|
if (!graphResult.ok) {
|
|
27636
27813
|
return { ok: false, error: graphResult.error };
|
|
@@ -27745,12 +27922,16 @@ function buildGraphOptions(pipeline, options) {
|
|
|
27745
27922
|
function toResult(graphResult, startTime, continueOnFailure) {
|
|
27746
27923
|
const durationMs = Date.now() - startTime;
|
|
27747
27924
|
const hasFailure = graphResult.nodeResults.some((r) => r.status === "failed");
|
|
27925
|
+
const policyBlockedNode = graphResult.nodeResults.find((r) => r.policyBlocked === true);
|
|
27748
27926
|
const stepResults = graphResult.nodeResults.map((r) => ({
|
|
27749
27927
|
stepId: r.nodeId,
|
|
27750
27928
|
status: mapNodeStatus(r.status),
|
|
27751
27929
|
durationMs: r.durationMs,
|
|
27752
27930
|
...r.error !== void 0 ? { error: r.error } : {}
|
|
27753
27931
|
}));
|
|
27932
|
+
if (policyBlockedNode !== void 0) {
|
|
27933
|
+
return policyBlockedResult(graphResult, durationMs, continueOnFailure, stepResults);
|
|
27934
|
+
}
|
|
27754
27935
|
if (hasFailure && !continueOnFailure) {
|
|
27755
27936
|
const failedNode = graphResult.nodeResults.find((r) => r.status === "failed");
|
|
27756
27937
|
return {
|
|
@@ -27773,6 +27954,17 @@ function toResult(graphResult, startTime, continueOnFailure) {
|
|
|
27773
27954
|
...!allOk && continueOnFailure ? { error: `${String(succeeded)}/${String(total)} steps succeeded` } : {}
|
|
27774
27955
|
};
|
|
27775
27956
|
}
|
|
27957
|
+
function policyBlockedResult(graphResult, durationMs, continueOnFailure, stepResults) {
|
|
27958
|
+
const blocked = graphResult.nodeResults.find((r) => r.policyBlocked === true);
|
|
27959
|
+
return {
|
|
27960
|
+
success: false,
|
|
27961
|
+
stepsExecuted: graphResult.stepsExecuted,
|
|
27962
|
+
durationMs,
|
|
27963
|
+
error: blocked?.error ?? "Policy gate blocked the pipeline",
|
|
27964
|
+
nodeResults: graphResult.nodeResults,
|
|
27965
|
+
...continueOnFailure ? { stepResults } : {}
|
|
27966
|
+
};
|
|
27967
|
+
}
|
|
27776
27968
|
function mapNodeStatus(status) {
|
|
27777
27969
|
if (status === "success") return "succeeded";
|
|
27778
27970
|
if (status === "interrupted") return "skipped";
|
|
@@ -27841,7 +28033,7 @@ async function flushTrace(ctx) {
|
|
|
27841
28033
|
}
|
|
27842
28034
|
|
|
27843
28035
|
// src/pipeline/policy-engine.ts
|
|
27844
|
-
var
|
|
28036
|
+
var logger21 = createLogger({ component: "PolicyEngine" });
|
|
27845
28037
|
var PolicyEngine = class {
|
|
27846
28038
|
rules = /* @__PURE__ */ new Map();
|
|
27847
28039
|
registerRule(rule) {
|
|
@@ -27855,7 +28047,7 @@ var PolicyEngine = class {
|
|
|
27855
28047
|
for (const rule of sorted) {
|
|
27856
28048
|
const decision = rule.evaluate(context);
|
|
27857
28049
|
if (!decision.allow) {
|
|
27858
|
-
|
|
28050
|
+
logger21.info("Policy rule blocked", {
|
|
27859
28051
|
ruleId: rule.id,
|
|
27860
28052
|
gateId: gate.id,
|
|
27861
28053
|
reason: decision.reason
|
|
@@ -27905,113 +28097,6 @@ function createDefaultPolicyEngine() {
|
|
|
27905
28097
|
return engine;
|
|
27906
28098
|
}
|
|
27907
28099
|
|
|
27908
|
-
// src/pipeline/v2-config.ts
|
|
27909
|
-
function readV2Mode() {
|
|
27910
|
-
const env = process.env["NEXUS_V2_MODE"];
|
|
27911
|
-
if (env === "off" || env === "partial") return env;
|
|
27912
|
-
return "full";
|
|
27913
|
-
}
|
|
27914
|
-
function resolveFlag(envKey, umbrellaDefault) {
|
|
27915
|
-
const env = process.env[envKey];
|
|
27916
|
-
if (env === "true") return true;
|
|
27917
|
-
if (env === "false") return false;
|
|
27918
|
-
return umbrellaDefault;
|
|
27919
|
-
}
|
|
27920
|
-
function resolvePolicyMode(umbrella) {
|
|
27921
|
-
const env = process.env["NEXUS_V2_POLICY_MODE"];
|
|
27922
|
-
if (env === "off" || env === "warn" || env === "block") return env;
|
|
27923
|
-
if (umbrella === "off") return "off";
|
|
27924
|
-
if (umbrella === "partial") return "warn";
|
|
27925
|
-
return "block";
|
|
27926
|
-
}
|
|
27927
|
-
function resolveV2Config() {
|
|
27928
|
-
const mode = readV2Mode();
|
|
27929
|
-
const umbrellaDelegate = mode !== "off";
|
|
27930
|
-
const umbrellaOrchestrate = mode === "full";
|
|
27931
|
-
return {
|
|
27932
|
-
mode,
|
|
27933
|
-
delegateEnabled: resolveFlag("NEXUS_V2_DELEGATE", umbrellaDelegate),
|
|
27934
|
-
orchestrateEnabled: resolveFlag("NEXUS_V2_ORCHESTRATE", umbrellaOrchestrate),
|
|
27935
|
-
policyMode: resolvePolicyMode(mode),
|
|
27936
|
-
aorchestraEnabled: resolveFlag("NEXUS_AORCHESTRA", true),
|
|
27937
|
-
dispatchEnabled: resolveFlag("NEXUS_AORCHESTRA_DISPATCH", true)
|
|
27938
|
-
};
|
|
27939
|
-
}
|
|
27940
|
-
|
|
27941
|
-
// src/pipeline/policy-evaluator.ts
|
|
27942
|
-
var logger21 = createLogger({ component: "PolicyEvaluator" });
|
|
27943
|
-
function getPolicyMode() {
|
|
27944
|
-
return resolveV2Config().policyMode;
|
|
27945
|
-
}
|
|
27946
|
-
function evaluatePipelinePolicy(options, context) {
|
|
27947
|
-
const mode = options.mode ?? getPolicyMode();
|
|
27948
|
-
if (mode === "off") {
|
|
27949
|
-
return { allowed: true, violations: [], mode };
|
|
27950
|
-
}
|
|
27951
|
-
const violations = [];
|
|
27952
|
-
const rules = options.engine.listRules();
|
|
27953
|
-
for (const rule of rules) {
|
|
27954
|
-
let decision;
|
|
27955
|
-
try {
|
|
27956
|
-
decision = rule.evaluate(context);
|
|
27957
|
-
} catch (err2) {
|
|
27958
|
-
const error = err2 instanceof Error ? err2 : new Error(String(err2));
|
|
27959
|
-
logger21.error("Policy rule threw during evaluation", error, {
|
|
27960
|
-
ruleId: rule.id,
|
|
27961
|
-
stageId: context.stageId
|
|
27962
|
-
});
|
|
27963
|
-
const message = error.message;
|
|
27964
|
-
violations.push({
|
|
27965
|
-
ruleId: rule.id,
|
|
27966
|
-
reason: `Rule threw during evaluation: ${message}`
|
|
27967
|
-
});
|
|
27968
|
-
continue;
|
|
27969
|
-
}
|
|
27970
|
-
if (!decision.allow) {
|
|
27971
|
-
violations.push({
|
|
27972
|
-
ruleId: rule.id,
|
|
27973
|
-
reason: decision.reason,
|
|
27974
|
-
...decision.escalateTo !== void 0 ? { escalateTo: decision.escalateTo } : {}
|
|
27975
|
-
});
|
|
27976
|
-
}
|
|
27977
|
-
}
|
|
27978
|
-
if (violations.length > 0) {
|
|
27979
|
-
emitPolicyEvents(options.eventBus, context, violations);
|
|
27980
|
-
logViolations(context, violations, mode);
|
|
27981
|
-
}
|
|
27982
|
-
const allowed = mode === "warn" || violations.length === 0;
|
|
27983
|
-
return { allowed, violations, mode };
|
|
27984
|
-
}
|
|
27985
|
-
function emitPolicyEvents(eventBus, context, violations) {
|
|
27986
|
-
if (eventBus === void 0) return;
|
|
27987
|
-
for (const v of violations) {
|
|
27988
|
-
const event = {
|
|
27989
|
-
type: "policy.evaluated",
|
|
27990
|
-
timestamp: Date.now(),
|
|
27991
|
-
executionId: context.taskId,
|
|
27992
|
-
gateId: `${context.stageId}:${v.ruleId}`,
|
|
27993
|
-
decision: "deny"
|
|
27994
|
-
};
|
|
27995
|
-
eventBus.emit(event);
|
|
27996
|
-
}
|
|
27997
|
-
}
|
|
27998
|
-
function logViolations(context, violations, mode) {
|
|
27999
|
-
const summary = violations.map((v) => v.ruleId).join(", ");
|
|
28000
|
-
if (mode === "block") {
|
|
28001
|
-
logger21.warn("Policy BLOCKED stage", {
|
|
28002
|
-
stageId: context.stageId,
|
|
28003
|
-
violations: summary,
|
|
28004
|
-
count: violations.length
|
|
28005
|
-
});
|
|
28006
|
-
} else {
|
|
28007
|
-
logger21.info("Policy WARN (violations logged)", {
|
|
28008
|
-
stageId: context.stageId,
|
|
28009
|
-
violations: summary,
|
|
28010
|
-
count: violations.length
|
|
28011
|
-
});
|
|
28012
|
-
}
|
|
28013
|
-
}
|
|
28014
|
-
|
|
28015
28100
|
// src/pipeline/task-contract-builders.ts
|
|
28016
28101
|
import { randomUUID as randomUUID9 } from "crypto";
|
|
28017
28102
|
function buildBaseTaskContract(input) {
|
|
@@ -49589,6 +49674,9 @@ export {
|
|
|
49589
49674
|
overwrite,
|
|
49590
49675
|
append,
|
|
49591
49676
|
customReducer,
|
|
49677
|
+
resolveV2Config,
|
|
49678
|
+
getPolicyMode,
|
|
49679
|
+
evaluatePipelinePolicy,
|
|
49592
49680
|
compilePlan,
|
|
49593
49681
|
TASK_STATUSES,
|
|
49594
49682
|
STAGE_TYPES,
|
|
@@ -49617,9 +49705,6 @@ export {
|
|
|
49617
49705
|
PolicyEngine,
|
|
49618
49706
|
BUILT_IN_RULES,
|
|
49619
49707
|
createDefaultPolicyEngine,
|
|
49620
|
-
resolveV2Config,
|
|
49621
|
-
getPolicyMode,
|
|
49622
|
-
evaluatePipelinePolicy,
|
|
49623
49708
|
createDelegatePipeline,
|
|
49624
49709
|
delegateInputToTaskContract,
|
|
49625
49710
|
executeDelegatePipeline,
|
|
@@ -49800,4 +49885,4 @@ export {
|
|
|
49800
49885
|
shutdownFeedbackSubscriber,
|
|
49801
49886
|
createEventBusBridge
|
|
49802
49887
|
};
|
|
49803
|
-
//# sourceMappingURL=chunk-
|
|
49888
|
+
//# sourceMappingURL=chunk-2SCNPVUP.js.map
|