@neuroverseos/governance 0.1.6 → 0.2.2

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 (82) hide show
  1. package/README.md +279 -423
  2. package/dist/adapters/express.cjs +242 -2
  3. package/dist/adapters/express.d.cts +1 -1
  4. package/dist/adapters/express.d.ts +1 -1
  5. package/dist/adapters/express.js +5 -3
  6. package/dist/adapters/index.cjs +337 -5
  7. package/dist/adapters/index.d.cts +1 -1
  8. package/dist/adapters/index.d.ts +1 -1
  9. package/dist/adapters/index.js +8 -6
  10. package/dist/adapters/langchain.cjs +297 -3
  11. package/dist/adapters/langchain.d.cts +8 -1
  12. package/dist/adapters/langchain.d.ts +8 -1
  13. package/dist/adapters/langchain.js +5 -3
  14. package/dist/adapters/openai.cjs +297 -3
  15. package/dist/adapters/openai.d.cts +8 -1
  16. package/dist/adapters/openai.d.ts +8 -1
  17. package/dist/adapters/openai.js +5 -3
  18. package/dist/adapters/openclaw.cjs +297 -3
  19. package/dist/adapters/openclaw.d.cts +8 -1
  20. package/dist/adapters/openclaw.d.ts +8 -1
  21. package/dist/adapters/openclaw.js +5 -3
  22. package/dist/{bootstrap-H4HHKQ5G.js → bootstrap-GXVDZNF7.js} +2 -1
  23. package/dist/{build-73KAVHEY.js → build-P42YFKQV.js} +34 -3
  24. package/dist/{chunk-Z2S2HIV5.js → chunk-2NICNKOM.js} +2 -2
  25. package/dist/{chunk-B4NF3OLW.js → chunk-4JRYGIO7.js} +56 -2
  26. package/dist/chunk-4QXB6PEO.js +232 -0
  27. package/dist/chunk-6CZSKEY5.js +164 -0
  28. package/dist/{chunk-O5OMJMIE.js → chunk-7P3S7MAY.js} +502 -2
  29. package/dist/chunk-A5W4GNQO.js +130 -0
  30. package/dist/chunk-AKW5YVCE.js +96 -0
  31. package/dist/chunk-DPVS43ZT.js +608 -0
  32. package/dist/{chunk-EIUHJXBB.js → chunk-GR6DGCZ2.js} +1 -1
  33. package/dist/chunk-KEST3MWO.js +324 -0
  34. package/dist/{chunk-D7BGWV2J.js → chunk-NF5POFCI.js} +5 -3
  35. package/dist/{chunk-FZQCRGUU.js → chunk-OHAC6HJE.js} +27 -3
  36. package/dist/chunk-OT6PXH54.js +61 -0
  37. package/dist/{chunk-ITJ3LCPG.js → chunk-PDOZHZWL.js} +1 -1
  38. package/dist/{chunk-T4X42QXC.js → chunk-Q6O7ZLO2.js} +0 -59
  39. package/dist/{chunk-FYPYZFV5.js → chunk-QPASI2BR.js} +1 -1
  40. package/dist/{chunk-EQXFOKH2.js → chunk-RWXVAH6P.js} +27 -3
  41. package/dist/{chunk-CROPZ75A.js → chunk-SKU3GAPD.js} +27 -3
  42. package/dist/chunk-YZFATT7X.js +9 -0
  43. package/dist/cli/neuroverse.cjs +5343 -732
  44. package/dist/cli/neuroverse.js +69 -13
  45. package/dist/cli/plan.cjs +1599 -0
  46. package/dist/cli/plan.d.cts +20 -0
  47. package/dist/cli/plan.d.ts +20 -0
  48. package/dist/cli/plan.js +361 -0
  49. package/dist/cli/run.cjs +1746 -0
  50. package/dist/cli/run.d.cts +20 -0
  51. package/dist/cli/run.d.ts +20 -0
  52. package/dist/cli/run.js +143 -0
  53. package/dist/{configure-ai-46JVG56I.js → configure-ai-TK67ZWZL.js} +5 -2
  54. package/dist/{derive-6NAEWLM5.js → derive-TLIV4OOU.js} +6 -4
  55. package/dist/doctor-QV6HELS5.js +170 -0
  56. package/dist/{explain-3B3VB6TL.js → explain-IDCRWMPX.js} +2 -1
  57. package/dist/{guard-67Y66P3I.js → guard-GFLQZY6U.js} +20 -6
  58. package/dist/{guard-contract-D_RQz9kt.d.ts → guard-contract-Cm91Kp4j.d.cts} +182 -2
  59. package/dist/{guard-contract-D_RQz9kt.d.cts → guard-contract-Cm91Kp4j.d.ts} +182 -2
  60. package/dist/guard-engine-JLTUARGU.js +10 -0
  61. package/dist/{impact-CHERK3O6.js → impact-XPECYRLH.js} +5 -3
  62. package/dist/{improve-YG6I6ERG.js → improve-GPUBKTEA.js} +4 -3
  63. package/dist/index.cjs +2135 -89
  64. package/dist/index.d.cts +481 -12
  65. package/dist/index.d.ts +481 -12
  66. package/dist/index.js +70 -20
  67. package/dist/{init-Z66T6TDI.js → init-PKPIYHYE.js} +2 -0
  68. package/dist/mcp-server-LZVJHBT5.js +13 -0
  69. package/dist/model-adapter-BB7G4MFI.js +11 -0
  70. package/dist/playground-FGOMASHN.js +550 -0
  71. package/dist/redteam-SK7AMIG3.js +357 -0
  72. package/dist/session-VISISNWJ.js +14 -0
  73. package/dist/{simulate-ETHHINZ4.js → simulate-VDOYQFRO.js} +2 -1
  74. package/dist/test-75AVHC3R.js +217 -0
  75. package/dist/{trace-3YODSSIP.js → trace-JVF67VR3.js} +4 -2
  76. package/dist/{validate-UVE6GKQU.js → validate-LLBWVPGV.js} +15 -6
  77. package/dist/validate-engine-UIABSIHD.js +7 -0
  78. package/dist/{world-WLNHL5XC.js → world-LAXO6DOX.js} +87 -7
  79. package/dist/world-loader-HMPTOEA2.js +9 -0
  80. package/package.json +19 -5
  81. package/dist/validate-engine-657D75OG.js +0 -6
  82. /package/dist/{chunk-M3TZFGHO.js → chunk-JZPQGIKR.js} +0 -0
@@ -47,6 +47,232 @@ __export(adapters_exports, {
47
47
  });
48
48
  module.exports = __toCommonJS(adapters_exports);
49
49
 
50
+ // src/engine/plan-engine.ts
51
+ function keywordMatch(eventText, step) {
52
+ const stepText = [
53
+ step.label,
54
+ step.description ?? "",
55
+ ...step.tags ?? []
56
+ ].join(" ").toLowerCase();
57
+ const keywords = stepText.split(/\s+/).filter((w) => w.length > 3);
58
+ if (keywords.length === 0) return false;
59
+ const matched = keywords.filter((kw) => eventText.includes(kw));
60
+ return matched.length >= Math.ceil(keywords.length * 0.5);
61
+ }
62
+ function tokenSimilarity(a, b) {
63
+ const tokensA = new Set(a.toLowerCase().split(/\s+/).filter((w) => w.length > 2));
64
+ const tokensB = new Set(b.toLowerCase().split(/\s+/).filter((w) => w.length > 2));
65
+ if (tokensA.size === 0 || tokensB.size === 0) return 0;
66
+ let intersection = 0;
67
+ for (const t of tokensA) {
68
+ if (tokensB.has(t)) intersection++;
69
+ }
70
+ const union = (/* @__PURE__ */ new Set([...tokensA, ...tokensB])).size;
71
+ return union > 0 ? intersection / union : 0;
72
+ }
73
+ function findMatchingStep(eventText, event, steps) {
74
+ const pendingOrActive = steps.filter((s) => s.status === "pending" || s.status === "active");
75
+ if (pendingOrActive.length === 0) {
76
+ return { matched: null, closest: null, closestScore: 0 };
77
+ }
78
+ for (const step of pendingOrActive) {
79
+ if (keywordMatch(eventText, step)) {
80
+ if (step.tools && event.tool && !step.tools.includes(event.tool)) {
81
+ continue;
82
+ }
83
+ return { matched: step, closest: step, closestScore: 1 };
84
+ }
85
+ }
86
+ const intentText = [event.intent, event.tool ?? "", event.scope ?? ""].join(" ");
87
+ let bestStep = null;
88
+ let bestScore = 0;
89
+ for (const step of pendingOrActive) {
90
+ const stepText = [step.label, step.description ?? "", ...step.tags ?? []].join(" ");
91
+ const score = tokenSimilarity(intentText, stepText);
92
+ if (score > bestScore) {
93
+ bestScore = score;
94
+ bestStep = step;
95
+ }
96
+ }
97
+ const SIMILARITY_THRESHOLD = 0.35;
98
+ if (bestScore >= SIMILARITY_THRESHOLD && bestStep) {
99
+ if (bestStep.tools && event.tool && !bestStep.tools.includes(event.tool)) {
100
+ return { matched: null, closest: bestStep, closestScore: bestScore };
101
+ }
102
+ return { matched: bestStep, closest: bestStep, closestScore: bestScore };
103
+ }
104
+ return { matched: null, closest: bestStep, closestScore: bestScore };
105
+ }
106
+ function isSequenceValid(step, plan) {
107
+ if (!plan.sequential) return true;
108
+ if (!step.requires || step.requires.length === 0) return true;
109
+ return step.requires.every((reqId) => {
110
+ const reqStep = plan.steps.find((s) => s.id === reqId);
111
+ return reqStep?.status === "completed";
112
+ });
113
+ }
114
+ function checkConstraints(event, eventText, constraints) {
115
+ const checks = [];
116
+ for (const constraint of constraints) {
117
+ if (constraint.type === "approval") {
118
+ if (constraint.trigger && eventText.includes(constraint.trigger.substring(0, 10).toLowerCase())) {
119
+ checks.push({ constraintId: constraint.id, passed: false, reason: constraint.description });
120
+ return { violated: constraint, checks };
121
+ }
122
+ const keywords = constraint.description.toLowerCase().split(/\s+/).filter((w) => w.length > 3);
123
+ const relevant = keywords.some((kw) => eventText.includes(kw));
124
+ if (relevant) {
125
+ checks.push({ constraintId: constraint.id, passed: false, reason: constraint.description });
126
+ return { violated: constraint, checks };
127
+ }
128
+ checks.push({ constraintId: constraint.id, passed: true });
129
+ continue;
130
+ }
131
+ if (constraint.type === "scope" && constraint.trigger) {
132
+ const keywords = constraint.trigger.split(/\s+/).filter((w) => w.length > 3);
133
+ const violated = keywords.length > 0 && keywords.every((kw) => eventText.includes(kw));
134
+ checks.push({
135
+ constraintId: constraint.id,
136
+ passed: !violated,
137
+ reason: violated ? constraint.description : void 0
138
+ });
139
+ if (violated) {
140
+ return { violated: constraint, checks };
141
+ }
142
+ continue;
143
+ }
144
+ checks.push({ constraintId: constraint.id, passed: true });
145
+ }
146
+ return { violated: null, checks };
147
+ }
148
+ function getPlanProgress(plan) {
149
+ const completed = plan.steps.filter((s) => s.status === "completed").length;
150
+ const total = plan.steps.length;
151
+ return {
152
+ completed,
153
+ total,
154
+ percentage: total > 0 ? Math.round(completed / total * 100) : 0
155
+ };
156
+ }
157
+ function advancePlan(plan, stepId, evidence) {
158
+ const step = plan.steps.find((s) => s.id === stepId);
159
+ if (!step) {
160
+ return { success: false, reason: `Step "${stepId}" not found in plan.` };
161
+ }
162
+ if (step.status === "completed") {
163
+ return { success: false, reason: `Step "${stepId}" is already completed.` };
164
+ }
165
+ const mode = plan.completion ?? "trust";
166
+ if (mode === "verified" && step.verify) {
167
+ if (!evidence) {
168
+ return {
169
+ success: false,
170
+ reason: `Step "${step.label}" requires evidence (verify: ${step.verify}). Provide evidence to advance.`
171
+ };
172
+ }
173
+ if (evidence.type !== step.verify) {
174
+ return {
175
+ success: false,
176
+ reason: `Evidence type "${evidence.type}" does not match required verification "${step.verify}".`
177
+ };
178
+ }
179
+ }
180
+ const updatedPlan = {
181
+ ...plan,
182
+ steps: plan.steps.map(
183
+ (s) => s.id === stepId ? { ...s, status: "completed" } : s
184
+ )
185
+ };
186
+ return {
187
+ success: true,
188
+ plan: updatedPlan,
189
+ evidence: evidence ?? void 0
190
+ };
191
+ }
192
+ function evaluatePlan(event, plan) {
193
+ const progress = getPlanProgress(plan);
194
+ if (plan.expires_at) {
195
+ const expiresAt = new Date(plan.expires_at).getTime();
196
+ if (Date.now() > expiresAt) {
197
+ return {
198
+ allowed: true,
199
+ status: "PLAN_COMPLETE",
200
+ reason: "Plan has expired.",
201
+ progress
202
+ };
203
+ }
204
+ }
205
+ if (progress.completed === progress.total) {
206
+ return {
207
+ allowed: true,
208
+ status: "PLAN_COMPLETE",
209
+ reason: "All plan steps are completed.",
210
+ progress
211
+ };
212
+ }
213
+ const eventText = [
214
+ event.intent,
215
+ event.tool ?? "",
216
+ event.scope ?? ""
217
+ ].join(" ").toLowerCase();
218
+ const { matched, closest, closestScore } = findMatchingStep(eventText, event, plan.steps);
219
+ if (!matched) {
220
+ return {
221
+ allowed: false,
222
+ status: "OFF_PLAN",
223
+ reason: "Action does not match any plan step.",
224
+ closestStep: closest?.label,
225
+ similarityScore: closestScore,
226
+ progress
227
+ };
228
+ }
229
+ if (!isSequenceValid(matched, plan)) {
230
+ const pendingDeps = (matched.requires ?? []).filter((reqId) => plan.steps.find((s) => s.id === reqId)?.status !== "completed").join(", ");
231
+ return {
232
+ allowed: false,
233
+ status: "OFF_PLAN",
234
+ reason: `Step "${matched.label}" requires completion of: ${pendingDeps}`,
235
+ matchedStep: matched.id,
236
+ progress
237
+ };
238
+ }
239
+ const { violated } = checkConstraints(event, eventText, plan.constraints);
240
+ if (violated) {
241
+ return {
242
+ allowed: false,
243
+ status: "CONSTRAINT_VIOLATED",
244
+ reason: violated.description,
245
+ matchedStep: matched.id,
246
+ progress
247
+ };
248
+ }
249
+ return {
250
+ allowed: true,
251
+ status: "ON_PLAN",
252
+ reason: `Matches step: ${matched.label}`,
253
+ matchedStep: matched.id,
254
+ progress
255
+ };
256
+ }
257
+ function buildPlanCheck(event, plan, verdict) {
258
+ const eventText = [event.intent, event.tool ?? "", event.scope ?? ""].join(" ").toLowerCase();
259
+ const { matched, closest, closestScore } = findMatchingStep(eventText, event, plan.steps);
260
+ const { checks: constraintChecks } = checkConstraints(event, eventText, plan.constraints);
261
+ const progress = getPlanProgress(plan);
262
+ return {
263
+ planId: plan.plan_id,
264
+ matched: !!matched,
265
+ matchedStepId: matched?.id,
266
+ matchedStepLabel: matched?.label,
267
+ closestStepId: !matched ? closest?.id : void 0,
268
+ closestStepLabel: !matched ? closest?.label : void 0,
269
+ similarityScore: !matched ? closestScore : void 0,
270
+ sequenceValid: matched ? isSequenceValid(matched, plan) : void 0,
271
+ constraintsChecked: constraintChecks,
272
+ progress: { completed: progress.completed, total: progress.total }
273
+ };
274
+ }
275
+
50
276
  // src/engine/guard-engine.ts
51
277
  var PROMPT_INJECTION_PATTERNS = [
52
278
  // Instruction override
@@ -138,6 +364,7 @@ function evaluateGuard(event, world, options = {}) {
138
364
  const eventText = (event.intent + " " + (event.tool ?? "") + " " + (event.scope ?? "")).toLowerCase();
139
365
  const invariantChecks = [];
140
366
  const safetyChecks = [];
367
+ let planCheckResult;
141
368
  const roleChecks = [];
142
369
  const guardChecks = [];
143
370
  const kernelRuleChecks = [];
@@ -165,6 +392,7 @@ function evaluateGuard(event, world, options = {}) {
165
392
  includeTrace ? buildTrace(
166
393
  invariantChecks,
167
394
  safetyChecks,
395
+ planCheckResult,
168
396
  roleChecks,
169
397
  guardChecks,
170
398
  kernelRuleChecks,
@@ -193,6 +421,7 @@ function evaluateGuard(event, world, options = {}) {
193
421
  includeTrace ? buildTrace(
194
422
  invariantChecks,
195
423
  safetyChecks,
424
+ planCheckResult,
196
425
  roleChecks,
197
426
  guardChecks,
198
427
  kernelRuleChecks,
@@ -203,6 +432,42 @@ function evaluateGuard(event, world, options = {}) {
203
432
  ) : void 0
204
433
  );
205
434
  }
435
+ if (options.plan) {
436
+ const planVerdict = evaluatePlan(event, options.plan);
437
+ planCheckResult = buildPlanCheck(event, options.plan, planVerdict);
438
+ if (!planVerdict.allowed && planVerdict.status !== "PLAN_COMPLETE") {
439
+ decidingLayer = "plan-enforcement";
440
+ decidingId = `plan-${options.plan.plan_id}`;
441
+ const planStatus = planVerdict.status === "CONSTRAINT_VIOLATED" ? "PAUSE" : "BLOCK";
442
+ let reason = planVerdict.reason ?? "Action blocked by plan.";
443
+ if (planVerdict.status === "OFF_PLAN" && planVerdict.closestStep) {
444
+ reason += ` Closest step: "${planVerdict.closestStep}" (similarity: ${(planVerdict.similarityScore ?? 0).toFixed(2)})`;
445
+ }
446
+ return buildVerdict(
447
+ planStatus,
448
+ reason,
449
+ `plan-${options.plan.plan_id}`,
450
+ void 0,
451
+ world,
452
+ level,
453
+ invariantChecks,
454
+ guardsMatched,
455
+ rulesMatched,
456
+ includeTrace ? buildTrace(
457
+ invariantChecks,
458
+ safetyChecks,
459
+ planCheckResult,
460
+ roleChecks,
461
+ guardChecks,
462
+ kernelRuleChecks,
463
+ levelChecks,
464
+ decidingLayer,
465
+ decidingId,
466
+ startTime
467
+ ) : void 0
468
+ );
469
+ }
470
+ }
206
471
  const roleVerdict = checkRoleRules(event, eventText, world, roleChecks);
207
472
  if (roleVerdict) {
208
473
  decidingLayer = "role";
@@ -220,6 +485,7 @@ function evaluateGuard(event, world, options = {}) {
220
485
  includeTrace ? buildTrace(
221
486
  invariantChecks,
222
487
  safetyChecks,
488
+ planCheckResult,
223
489
  roleChecks,
224
490
  guardChecks,
225
491
  kernelRuleChecks,
@@ -248,6 +514,7 @@ function evaluateGuard(event, world, options = {}) {
248
514
  includeTrace ? buildTrace(
249
515
  invariantChecks,
250
516
  safetyChecks,
517
+ planCheckResult,
251
518
  roleChecks,
252
519
  guardChecks,
253
520
  kernelRuleChecks,
@@ -276,6 +543,7 @@ function evaluateGuard(event, world, options = {}) {
276
543
  includeTrace ? buildTrace(
277
544
  invariantChecks,
278
545
  safetyChecks,
546
+ planCheckResult,
279
547
  roleChecks,
280
548
  guardChecks,
281
549
  kernelRuleChecks,
@@ -303,6 +571,7 @@ function evaluateGuard(event, world, options = {}) {
303
571
  includeTrace ? buildTrace(
304
572
  invariantChecks,
305
573
  safetyChecks,
574
+ planCheckResult,
306
575
  roleChecks,
307
576
  guardChecks,
308
577
  kernelRuleChecks,
@@ -327,6 +596,7 @@ function evaluateGuard(event, world, options = {}) {
327
596
  includeTrace ? buildTrace(
328
597
  invariantChecks,
329
598
  safetyChecks,
599
+ planCheckResult,
330
600
  roleChecks,
331
601
  guardChecks,
332
602
  kernelRuleChecks,
@@ -664,8 +934,8 @@ function matchesKeywords(eventText, ruleText) {
664
934
  function eventToAllowlistKey(event) {
665
935
  return `${(event.tool ?? "*").toLowerCase()}::${event.intent.toLowerCase().trim()}`;
666
936
  }
667
- function buildTrace(invariantChecks, safetyChecks, roleChecks, guardChecks, kernelRuleChecks, levelChecks, decidingLayer, decidingId, startTime) {
668
- return {
937
+ function buildTrace(invariantChecks, safetyChecks, planCheck, roleChecks, guardChecks, kernelRuleChecks, levelChecks, decidingLayer, decidingId, startTime) {
938
+ const trace = {
669
939
  invariantChecks,
670
940
  safetyChecks,
671
941
  roleChecks,
@@ -683,6 +953,7 @@ function buildTrace(invariantChecks, safetyChecks, roleChecks, guardChecks, kern
683
953
  "safety-scope-escape",
684
954
  "safety-execution-claim",
685
955
  "safety-execution-intent",
956
+ "plan-enforcement",
686
957
  "role-rules",
687
958
  "declarative-guards",
688
959
  "kernel-rules",
@@ -692,6 +963,10 @@ function buildTrace(invariantChecks, safetyChecks, roleChecks, guardChecks, kern
692
963
  },
693
964
  durationMs: performance.now() - startTime
694
965
  };
966
+ if (planCheck) {
967
+ trace.planCheck = planCheck;
968
+ }
969
+ return trace;
695
970
  }
696
971
  function buildVerdict(status, reason, ruleId, warning, world, level, invariantChecks, guardsMatched, rulesMatched, trace) {
697
972
  const evidence = {
@@ -817,12 +1092,15 @@ var NeuroVerseCallbackHandler = class {
817
1092
  options;
818
1093
  engineOptions;
819
1094
  mapToolCall;
1095
+ activePlan;
820
1096
  constructor(world, options = {}) {
821
1097
  this.world = world;
822
1098
  this.options = options;
1099
+ this.activePlan = options.plan;
823
1100
  this.engineOptions = {
824
1101
  trace: options.trace ?? false,
825
- level: options.level
1102
+ level: options.level,
1103
+ plan: this.activePlan
826
1104
  };
827
1105
  this.mapToolCall = options.mapToolCall ?? defaultMapToolCall;
828
1106
  }
@@ -841,6 +1119,7 @@ var NeuroVerseCallbackHandler = class {
841
1119
  parsedInput = { raw: input };
842
1120
  }
843
1121
  const event = this.mapToolCall(tool.name, parsedInput);
1122
+ this.engineOptions.plan = this.activePlan;
844
1123
  const verdict = evaluateGuard(event, this.world, this.engineOptions);
845
1124
  this.options.onEvaluate?.(verdict, event);
846
1125
  if (verdict.status === "BLOCK") {
@@ -853,6 +1132,21 @@ var NeuroVerseCallbackHandler = class {
853
1132
  throw new GovernanceBlockedError(verdict, event);
854
1133
  }
855
1134
  }
1135
+ if (verdict.status === "ALLOW" && this.activePlan) {
1136
+ const planVerdict = evaluatePlan(event, this.activePlan);
1137
+ if (planVerdict.matchedStep) {
1138
+ const advResult = advancePlan(this.activePlan, planVerdict.matchedStep);
1139
+ if (advResult.success && advResult.plan) {
1140
+ this.activePlan = advResult.plan;
1141
+ this.engineOptions.plan = this.activePlan;
1142
+ }
1143
+ const progress = getPlanProgress(this.activePlan);
1144
+ this.options.onPlanProgress?.(progress);
1145
+ if (progress.completed === progress.total) {
1146
+ this.options.onPlanComplete?.();
1147
+ }
1148
+ }
1149
+ }
856
1150
  }
857
1151
  };
858
1152
  async function createNeuroVerseCallbackHandler(worldPath, options) {
@@ -892,12 +1186,15 @@ var GovernedToolExecutor = class {
892
1186
  engineOptions;
893
1187
  mapFn;
894
1188
  blockMsg;
1189
+ activePlan;
895
1190
  constructor(world, options = {}) {
896
1191
  this.world = world;
897
1192
  this.options = options;
1193
+ this.activePlan = options.plan;
898
1194
  this.engineOptions = {
899
1195
  trace: options.trace ?? false,
900
- level: options.level
1196
+ level: options.level,
1197
+ plan: this.activePlan
901
1198
  };
902
1199
  this.mapFn = options.mapFunctionCall ?? defaultMapFunctionCall;
903
1200
  this.blockMsg = options.blockMessage ?? defaultBlockMessage;
@@ -914,8 +1211,24 @@ var GovernedToolExecutor = class {
914
1211
  args = { raw: toolCall.function.arguments };
915
1212
  }
916
1213
  const event = this.mapFn(toolCall.function.name, args);
1214
+ this.engineOptions.plan = this.activePlan;
917
1215
  const verdict = evaluateGuard(event, this.world, this.engineOptions);
918
1216
  this.options.onEvaluate?.(verdict, event);
1217
+ if (verdict.status === "ALLOW" && this.activePlan) {
1218
+ const planVerdict = evaluatePlan(event, this.activePlan);
1219
+ if (planVerdict.matchedStep) {
1220
+ const advResult = advancePlan(this.activePlan, planVerdict.matchedStep);
1221
+ if (advResult.success && advResult.plan) {
1222
+ this.activePlan = advResult.plan;
1223
+ this.engineOptions.plan = this.activePlan;
1224
+ }
1225
+ const progress = getPlanProgress(this.activePlan);
1226
+ this.options.onPlanProgress?.(progress);
1227
+ if (progress.completed === progress.total) {
1228
+ this.options.onPlanComplete?.();
1229
+ }
1230
+ }
1231
+ }
919
1232
  return verdict;
920
1233
  }
921
1234
  /**
@@ -991,12 +1304,15 @@ var NeuroVersePlugin = class {
991
1304
  options;
992
1305
  engineOptions;
993
1306
  mapAction;
1307
+ activePlan;
994
1308
  constructor(world, options = {}) {
995
1309
  this.world = world;
996
1310
  this.options = options;
1311
+ this.activePlan = options.plan;
997
1312
  this.engineOptions = {
998
1313
  trace: options.trace ?? false,
999
- level: options.level
1314
+ level: options.level,
1315
+ plan: this.activePlan
1000
1316
  };
1001
1317
  this.mapAction = options.mapAction ?? defaultMapAction;
1002
1318
  }
@@ -1008,6 +1324,7 @@ var NeuroVersePlugin = class {
1008
1324
  */
1009
1325
  beforeAction(action) {
1010
1326
  const event = this.mapAction(action, "input");
1327
+ this.engineOptions.plan = this.activePlan;
1011
1328
  const verdict = evaluateGuard(event, this.world, this.engineOptions);
1012
1329
  const result = {
1013
1330
  allowed: verdict.status === "ALLOW",
@@ -1018,6 +1335,21 @@ var NeuroVersePlugin = class {
1018
1335
  if (verdict.status === "BLOCK") {
1019
1336
  throw new GovernanceBlockedError3(verdict, action);
1020
1337
  }
1338
+ if (verdict.status === "ALLOW" && this.activePlan) {
1339
+ const planVerdict = evaluatePlan(event, this.activePlan);
1340
+ if (planVerdict.matchedStep) {
1341
+ const advResult = advancePlan(this.activePlan, planVerdict.matchedStep);
1342
+ if (advResult.success && advResult.plan) {
1343
+ this.activePlan = advResult.plan;
1344
+ this.engineOptions.plan = this.activePlan;
1345
+ }
1346
+ const progress = getPlanProgress(this.activePlan);
1347
+ this.options.onPlanProgress?.(progress);
1348
+ if (progress.completed === progress.total) {
1349
+ this.options.onPlanComplete?.();
1350
+ }
1351
+ }
1352
+ }
1021
1353
  return result;
1022
1354
  }
1023
1355
  /**
@@ -2,4 +2,4 @@ export { GovernanceBlockedError as LangChainGovernanceBlockedError, NeuroVerseCa
2
2
  export { GovernedExecutorOptions, GovernedToolExecutor, GovernedToolResult, GovernanceBlockedError as OpenAIGovernanceBlockedError, OpenAIToolCall, createGovernedToolExecutor, createGovernedToolExecutorFromWorld } from './openai.cjs';
3
3
  export { AgentAction, HookResult, NeuroVersePlugin, NeuroVersePluginOptions, GovernanceBlockedError as OpenClawGovernanceBlockedError, createNeuroVersePlugin, createNeuroVersePluginFromWorld } from './openclaw.cjs';
4
4
  export { GovernanceMiddlewareOptions, GovernanceRequest, GovernanceResponse, createGovernanceMiddleware, createGovernanceMiddlewareFromWorld } from './express.cjs';
5
- import '../guard-contract-D_RQz9kt.cjs';
5
+ import '../guard-contract-Cm91Kp4j.cjs';
@@ -2,4 +2,4 @@ export { GovernanceBlockedError as LangChainGovernanceBlockedError, NeuroVerseCa
2
2
  export { GovernedExecutorOptions, GovernedToolExecutor, GovernedToolResult, GovernanceBlockedError as OpenAIGovernanceBlockedError, OpenAIToolCall, createGovernedToolExecutor, createGovernedToolExecutorFromWorld } from './openai.js';
3
3
  export { AgentAction, HookResult, NeuroVersePlugin, NeuroVersePluginOptions, GovernanceBlockedError as OpenClawGovernanceBlockedError, createNeuroVersePlugin, createNeuroVersePluginFromWorld } from './openclaw.js';
4
4
  export { GovernanceMiddlewareOptions, GovernanceRequest, GovernanceResponse, createGovernanceMiddleware, createGovernanceMiddlewareFromWorld } from './express.js';
5
- import '../guard-contract-D_RQz9kt.js';
5
+ import '../guard-contract-Cm91Kp4j.js';
@@ -1,27 +1,29 @@
1
1
  import {
2
2
  createGovernanceMiddleware,
3
3
  createGovernanceMiddlewareFromWorld
4
- } from "../chunk-Z2S2HIV5.js";
4
+ } from "../chunk-2NICNKOM.js";
5
5
  import {
6
6
  GovernanceBlockedError,
7
7
  NeuroVerseCallbackHandler,
8
8
  createNeuroVerseCallbackHandler,
9
9
  createNeuroVerseCallbackHandlerFromWorld
10
- } from "../chunk-EQXFOKH2.js";
10
+ } from "../chunk-RWXVAH6P.js";
11
11
  import {
12
12
  GovernanceBlockedError as GovernanceBlockedError2,
13
13
  GovernedToolExecutor,
14
14
  createGovernedToolExecutor,
15
15
  createGovernedToolExecutorFromWorld
16
- } from "../chunk-FZQCRGUU.js";
16
+ } from "../chunk-OHAC6HJE.js";
17
17
  import {
18
18
  GovernanceBlockedError as GovernanceBlockedError3,
19
19
  NeuroVersePlugin,
20
20
  createNeuroVersePlugin,
21
21
  createNeuroVersePluginFromWorld
22
- } from "../chunk-CROPZ75A.js";
23
- import "../chunk-B4NF3OLW.js";
24
- import "../chunk-M3TZFGHO.js";
22
+ } from "../chunk-SKU3GAPD.js";
23
+ import "../chunk-4JRYGIO7.js";
24
+ import "../chunk-JZPQGIKR.js";
25
+ import "../chunk-4QXB6PEO.js";
26
+ import "../chunk-YZFATT7X.js";
25
27
  export {
26
28
  GovernedToolExecutor,
27
29
  GovernanceBlockedError as LangChainGovernanceBlockedError,