@neuroverseos/governance 0.1.0 → 0.1.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 (94) hide show
  1. package/LICENSE.md +190 -0
  2. package/README.md +472 -115
  3. package/dist/adapters/express.cjs +874 -0
  4. package/dist/adapters/express.d.cts +66 -0
  5. package/dist/adapters/express.d.ts +66 -0
  6. package/dist/adapters/express.js +10 -0
  7. package/dist/adapters/index.cjs +1166 -0
  8. package/dist/adapters/index.d.cts +5 -0
  9. package/dist/adapters/index.d.ts +5 -0
  10. package/dist/adapters/index.js +40 -0
  11. package/dist/adapters/langchain.cjs +861 -0
  12. package/dist/adapters/langchain.d.cts +82 -0
  13. package/dist/adapters/langchain.d.ts +82 -0
  14. package/dist/adapters/langchain.js +14 -0
  15. package/dist/adapters/openai.cjs +891 -0
  16. package/dist/adapters/openai.d.cts +92 -0
  17. package/dist/adapters/openai.d.ts +92 -0
  18. package/dist/adapters/openai.js +14 -0
  19. package/dist/adapters/openclaw.cjs +883 -0
  20. package/dist/adapters/openclaw.d.cts +92 -0
  21. package/dist/adapters/openclaw.d.ts +92 -0
  22. package/dist/adapters/openclaw.js +14 -0
  23. package/dist/bootstrap-H4HHKQ5G.js +113 -0
  24. package/dist/build-73KAVHEY.js +308 -0
  25. package/dist/chunk-4NGDRRQH.js +10 -0
  26. package/dist/chunk-B4NF3OLW.js +673 -0
  27. package/dist/chunk-BUWWN2NX.js +192 -0
  28. package/dist/chunk-CROPZ75A.js +107 -0
  29. package/dist/chunk-D7BGWV2J.js +620 -0
  30. package/dist/chunk-EIUHJXBB.js +340 -0
  31. package/dist/chunk-EQXFOKH2.js +85 -0
  32. package/dist/chunk-FYPYZFV5.js +187 -0
  33. package/dist/chunk-FYS2CBUW.js +304 -0
  34. package/dist/chunk-FZQCRGUU.js +115 -0
  35. package/dist/chunk-I3RRAYK2.js +11 -0
  36. package/dist/chunk-ITJ3LCPG.js +225 -0
  37. package/dist/chunk-M3TZFGHO.js +79 -0
  38. package/dist/chunk-MWDQ4MJB.js +11 -0
  39. package/dist/chunk-O5OMJMIE.js +590 -0
  40. package/dist/chunk-T4X42QXC.js +121 -0
  41. package/dist/chunk-XPDMYECO.js +642 -0
  42. package/dist/chunk-Z2S2HIV5.js +100 -0
  43. package/dist/cli/neuroverse.cjs +5864 -0
  44. package/dist/cli/neuroverse.d.cts +1 -0
  45. package/dist/cli/neuroverse.d.ts +1 -0
  46. package/dist/cli/neuroverse.js +128 -0
  47. package/dist/configure-ai-46JVG56I.js +129 -0
  48. package/dist/derive-6NAEWLM5.js +150 -0
  49. package/dist/explain-3B3VB6TL.js +69 -0
  50. package/dist/guard-67Y66P3I.js +82 -0
  51. package/dist/guard-contract-D_RQz9kt.d.cts +529 -0
  52. package/dist/guard-contract-D_RQz9kt.d.ts +529 -0
  53. package/dist/impact-CHERK3O6.js +57 -0
  54. package/dist/improve-YG6I6ERG.js +84 -0
  55. package/dist/index.cjs +4227 -0
  56. package/dist/index.d.cts +1147 -0
  57. package/dist/index.d.ts +1139 -25
  58. package/dist/index.js +318 -1159
  59. package/dist/init-Z66T6TDI.js +142 -0
  60. package/dist/simulate-ETHHINZ4.js +107 -0
  61. package/dist/trace-3YODSSIP.js +164 -0
  62. package/dist/validate-UVE6GKQU.js +72 -0
  63. package/dist/validate-engine-657D75OG.js +6 -0
  64. package/dist/world-WLNHL5XC.js +298 -0
  65. package/dist/worlds/derivation-world.nv-world.md +278 -0
  66. package/package.json +74 -26
  67. package/LICENSE +0 -21
  68. package/dist/audit-logger.d.ts +0 -38
  69. package/dist/audit-logger.d.ts.map +0 -1
  70. package/dist/audit-logger.js +0 -100
  71. package/dist/audit-logger.js.map +0 -1
  72. package/dist/condition-engine.d.ts +0 -16
  73. package/dist/condition-engine.d.ts.map +0 -1
  74. package/dist/condition-engine.js +0 -186
  75. package/dist/condition-engine.js.map +0 -1
  76. package/dist/drift-monitor.d.ts +0 -81
  77. package/dist/drift-monitor.d.ts.map +0 -1
  78. package/dist/drift-monitor.js +0 -228
  79. package/dist/drift-monitor.js.map +0 -1
  80. package/dist/governance-engine.d.ts +0 -131
  81. package/dist/governance-engine.d.ts.map +0 -1
  82. package/dist/governance-engine.js +0 -660
  83. package/dist/governance-engine.js.map +0 -1
  84. package/dist/index.d.ts.map +0 -1
  85. package/dist/index.js.map +0 -1
  86. package/dist/types.d.ts +0 -196
  87. package/dist/types.d.ts.map +0 -1
  88. package/dist/types.js +0 -9
  89. package/dist/types.js.map +0 -1
  90. package/dist/world-bootstrap.d.ts +0 -31
  91. package/dist/world-bootstrap.d.ts.map +0 -1
  92. package/dist/world-bootstrap.js +0 -415
  93. package/dist/world-bootstrap.js.map +0 -1
  94. package/openclaw.plugin.json +0 -59
@@ -0,0 +1,1166 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/adapters/index.ts
31
+ var adapters_exports = {};
32
+ __export(adapters_exports, {
33
+ GovernedToolExecutor: () => GovernedToolExecutor,
34
+ LangChainGovernanceBlockedError: () => GovernanceBlockedError,
35
+ NeuroVerseCallbackHandler: () => NeuroVerseCallbackHandler,
36
+ NeuroVersePlugin: () => NeuroVersePlugin,
37
+ OpenAIGovernanceBlockedError: () => GovernanceBlockedError2,
38
+ OpenClawGovernanceBlockedError: () => GovernanceBlockedError3,
39
+ createGovernanceMiddleware: () => createGovernanceMiddleware,
40
+ createGovernanceMiddlewareFromWorld: () => createGovernanceMiddlewareFromWorld,
41
+ createGovernedToolExecutor: () => createGovernedToolExecutor,
42
+ createGovernedToolExecutorFromWorld: () => createGovernedToolExecutorFromWorld,
43
+ createNeuroVerseCallbackHandler: () => createNeuroVerseCallbackHandler,
44
+ createNeuroVerseCallbackHandlerFromWorld: () => createNeuroVerseCallbackHandlerFromWorld,
45
+ createNeuroVersePlugin: () => createNeuroVersePlugin,
46
+ createNeuroVersePluginFromWorld: () => createNeuroVersePluginFromWorld
47
+ });
48
+ module.exports = __toCommonJS(adapters_exports);
49
+
50
+ // src/engine/guard-engine.ts
51
+ var PROMPT_INJECTION_PATTERNS = [
52
+ // Instruction override
53
+ { pattern: /ignore\s+(previous|all|prior|above)\s+(instructions?|rules?)/i, label: "ignore-instructions" },
54
+ { pattern: /disregard\s+(your|the)\s+(rules|constraints)/i, label: "disregard-rules" },
55
+ { pattern: /new\s+instructions?:/i, label: "new-instructions" },
56
+ // Identity manipulation
57
+ { pattern: /you\s+are\s+now/i, label: "identity-override" },
58
+ { pattern: /new\s+persona/i, label: "new-persona" },
59
+ { pattern: /act\s+as\s+if/i, label: "act-as-if" },
60
+ { pattern: /pretend\s+(you|to\s+be|you\s+are\s+unrestricted)/i, label: "pretend-to-be" },
61
+ // Context reset
62
+ { pattern: /forget\s+(everything|all|your)/i, label: "forget-context" },
63
+ { pattern: /system\s*:\s*override/i, label: "system-override" },
64
+ // Constraint bypass
65
+ { pattern: /override\s+(your|the)\s+(programming|constraints)/i, label: "override-constraints" },
66
+ { pattern: /bypass\s+(your|the)\s+(filters|constraints|rules)/i, label: "bypass-filters" },
67
+ // Prompt extraction
68
+ { pattern: /system\s+prompt/i, label: "system-prompt-probe" },
69
+ { pattern: /reveal\s+your\s+(instructions?|prompt|rules)/i, label: "reveal-instructions" },
70
+ // Known jailbreak terms
71
+ { pattern: /jailbreak/i, label: "jailbreak" },
72
+ { pattern: /DAN\s+mode/i, label: "dan-mode" },
73
+ { pattern: /developer\s+mode/i, label: "developer-mode" }
74
+ ];
75
+ var EXECUTION_CLAIM_PATTERNS = [
76
+ { pattern: /I have (executed|completed|performed|done|made|created|sent|deleted|modified|updated)/i, label: "claim-i-have" },
77
+ { pattern: /Successfully (created|deleted|modified|updated|sent|executed|performed)/i, label: "claim-successfully" },
78
+ { pattern: /The file has been/i, label: "claim-file-modified" },
79
+ { pattern: /I've made the changes/i, label: "claim-made-changes" },
80
+ { pattern: /I('ve| have) (sent|posted|submitted|uploaded|downloaded)/i, label: "claim-sent" },
81
+ { pattern: /Your (email|message|file|request) has been (sent|submitted)/i, label: "claim-your-sent" },
82
+ { pattern: /Transaction complete/i, label: "claim-transaction" },
83
+ { pattern: /Order placed/i, label: "claim-order" },
84
+ { pattern: /Payment processed/i, label: "claim-payment" }
85
+ ];
86
+ var EXECUTION_INTENT_PATTERNS = [
87
+ { pattern: /^(execute|run|perform|do this)/i, label: "intent-execute" },
88
+ { pattern: /^(create|write|delete|modify) (a |the )?(file|folder|document)/i, label: "intent-file-ops" },
89
+ { pattern: /^(send|post|submit) (a |an |the )?(email|message|tweet|post)/i, label: "intent-send" },
90
+ { pattern: /^(search|look up|browse) (the )?web/i, label: "intent-web-search" },
91
+ { pattern: /^(make|call|invoke) (a |an )?(api|http|rest) (call|request)/i, label: "intent-api-call" },
92
+ { pattern: /^(buy|purchase|order|pay|transfer|send money)/i, label: "intent-financial" },
93
+ { pattern: /^(book|schedule|reserve)/i, label: "intent-booking" },
94
+ { pattern: /^(download|upload|save to|export to)/i, label: "intent-transfer" }
95
+ ];
96
+ var SCOPE_ESCAPE_PATTERNS = [
97
+ { pattern: /\.\.\//, label: "parent-traversal" },
98
+ { pattern: /^\/(?!home|project|workspace)/i, label: "absolute-path-outside-safe" },
99
+ { pattern: /~\//, label: "home-directory" },
100
+ { pattern: /\/etc\//i, label: "system-config" },
101
+ { pattern: /\/usr\//i, label: "system-binaries" },
102
+ { pattern: /\/var\//i, label: "system-variable-data" }
103
+ ];
104
+ var NEUTRAL_MESSAGES = {
105
+ "prompt-injection": "This input contains patterns that could alter agent behavior.",
106
+ "scope-escape": "This action would affect resources outside the declared scope.",
107
+ "execution-claim": "This response claims to have performed an action.",
108
+ "execution-intent": "This input requests execution in a thinking-only environment.",
109
+ "delete": "This action would remove files. Confirmation needed.",
110
+ "write-external": "This action would write outside the project folder.",
111
+ "network-mutate": "This action would send data to an external service.",
112
+ "credential-access": "This action would access stored credentials."
113
+ };
114
+ function levelRequiresConfirmation(level, actionType) {
115
+ if (level === "strict") return true;
116
+ if (level === "standard") {
117
+ return actionType === "delete" || actionType === "credential-access";
118
+ }
119
+ return false;
120
+ }
121
+ function isExternalScope(scope) {
122
+ const internalPatterns = [
123
+ /^\.?\/?src\//i,
124
+ /^\.?\/?lib\//i,
125
+ /^\.?\/?app\//i,
126
+ /^\.?\/?components\//i,
127
+ /^\.?\/?pages\//i,
128
+ /^\.?\/?public\//i,
129
+ /^\.?\/?assets\//i,
130
+ /^\.\//
131
+ ];
132
+ return !internalPatterns.some((p) => p.test(scope));
133
+ }
134
+ function evaluateGuard(event, world, options = {}) {
135
+ const startTime = performance.now();
136
+ const level = options.level ?? "standard";
137
+ const includeTrace = options.trace ?? false;
138
+ const eventText = (event.intent + " " + (event.tool ?? "") + " " + (event.scope ?? "")).toLowerCase();
139
+ const invariantChecks = [];
140
+ const safetyChecks = [];
141
+ const roleChecks = [];
142
+ const guardChecks = [];
143
+ const kernelRuleChecks = [];
144
+ const levelChecks = [];
145
+ let decidingLayer = "default-allow";
146
+ let decidingId;
147
+ const guardsMatched = [];
148
+ const rulesMatched = [];
149
+ checkInvariantCoverage(world, invariantChecks);
150
+ if (options.sessionAllowlist) {
151
+ const key = eventToAllowlistKey(event);
152
+ if (options.sessionAllowlist.has(key)) {
153
+ decidingLayer = "session-allowlist";
154
+ decidingId = `allowlist:${key}`;
155
+ return buildVerdict(
156
+ "ALLOW",
157
+ void 0,
158
+ `allowlist:${key}`,
159
+ void 0,
160
+ world,
161
+ level,
162
+ invariantChecks,
163
+ guardsMatched,
164
+ rulesMatched,
165
+ includeTrace ? buildTrace(
166
+ invariantChecks,
167
+ safetyChecks,
168
+ roleChecks,
169
+ guardChecks,
170
+ kernelRuleChecks,
171
+ levelChecks,
172
+ decidingLayer,
173
+ decidingId,
174
+ startTime
175
+ ) : void 0
176
+ );
177
+ }
178
+ }
179
+ const safetyVerdict = checkSafety(event, eventText, safetyChecks);
180
+ if (safetyVerdict) {
181
+ decidingLayer = "safety";
182
+ decidingId = safetyVerdict.ruleId;
183
+ return buildVerdict(
184
+ safetyVerdict.status,
185
+ safetyVerdict.reason,
186
+ safetyVerdict.ruleId,
187
+ void 0,
188
+ world,
189
+ level,
190
+ invariantChecks,
191
+ guardsMatched,
192
+ rulesMatched,
193
+ includeTrace ? buildTrace(
194
+ invariantChecks,
195
+ safetyChecks,
196
+ roleChecks,
197
+ guardChecks,
198
+ kernelRuleChecks,
199
+ levelChecks,
200
+ decidingLayer,
201
+ decidingId,
202
+ startTime
203
+ ) : void 0
204
+ );
205
+ }
206
+ const roleVerdict = checkRoleRules(event, eventText, world, roleChecks);
207
+ if (roleVerdict) {
208
+ decidingLayer = "role";
209
+ decidingId = roleVerdict.ruleId;
210
+ return buildVerdict(
211
+ roleVerdict.status,
212
+ roleVerdict.reason,
213
+ roleVerdict.ruleId,
214
+ void 0,
215
+ world,
216
+ level,
217
+ invariantChecks,
218
+ guardsMatched,
219
+ rulesMatched,
220
+ includeTrace ? buildTrace(
221
+ invariantChecks,
222
+ safetyChecks,
223
+ roleChecks,
224
+ guardChecks,
225
+ kernelRuleChecks,
226
+ levelChecks,
227
+ decidingLayer,
228
+ decidingId,
229
+ startTime
230
+ ) : void 0
231
+ );
232
+ }
233
+ const guardVerdict = checkGuards(event, eventText, world, guardChecks, guardsMatched);
234
+ if (guardVerdict) {
235
+ if (guardVerdict.status !== "ALLOW") {
236
+ decidingLayer = "guard";
237
+ decidingId = guardVerdict.ruleId;
238
+ return buildVerdict(
239
+ guardVerdict.status,
240
+ guardVerdict.reason,
241
+ guardVerdict.ruleId,
242
+ void 0,
243
+ world,
244
+ level,
245
+ invariantChecks,
246
+ guardsMatched,
247
+ rulesMatched,
248
+ includeTrace ? buildTrace(
249
+ invariantChecks,
250
+ safetyChecks,
251
+ roleChecks,
252
+ guardChecks,
253
+ kernelRuleChecks,
254
+ levelChecks,
255
+ decidingLayer,
256
+ decidingId,
257
+ startTime
258
+ ) : void 0
259
+ );
260
+ }
261
+ }
262
+ const kernelVerdict = checkKernelRules(eventText, world, kernelRuleChecks, rulesMatched);
263
+ if (kernelVerdict) {
264
+ decidingLayer = "kernel-rule";
265
+ decidingId = kernelVerdict.ruleId;
266
+ return buildVerdict(
267
+ kernelVerdict.status,
268
+ kernelVerdict.reason,
269
+ kernelVerdict.ruleId,
270
+ void 0,
271
+ world,
272
+ level,
273
+ invariantChecks,
274
+ guardsMatched,
275
+ rulesMatched,
276
+ includeTrace ? buildTrace(
277
+ invariantChecks,
278
+ safetyChecks,
279
+ roleChecks,
280
+ guardChecks,
281
+ kernelRuleChecks,
282
+ levelChecks,
283
+ decidingLayer,
284
+ decidingId,
285
+ startTime
286
+ ) : void 0
287
+ );
288
+ }
289
+ const levelVerdict = checkLevelConstraints(event, level, levelChecks);
290
+ if (levelVerdict) {
291
+ decidingLayer = "level-constraint";
292
+ decidingId = levelVerdict.ruleId;
293
+ return buildVerdict(
294
+ levelVerdict.status,
295
+ levelVerdict.reason,
296
+ levelVerdict.ruleId,
297
+ void 0,
298
+ world,
299
+ level,
300
+ invariantChecks,
301
+ guardsMatched,
302
+ rulesMatched,
303
+ includeTrace ? buildTrace(
304
+ invariantChecks,
305
+ safetyChecks,
306
+ roleChecks,
307
+ guardChecks,
308
+ kernelRuleChecks,
309
+ levelChecks,
310
+ decidingLayer,
311
+ decidingId,
312
+ startTime
313
+ ) : void 0
314
+ );
315
+ }
316
+ const warning = guardVerdict?.warning;
317
+ return buildVerdict(
318
+ "ALLOW",
319
+ void 0,
320
+ void 0,
321
+ warning,
322
+ world,
323
+ level,
324
+ invariantChecks,
325
+ guardsMatched,
326
+ rulesMatched,
327
+ includeTrace ? buildTrace(
328
+ invariantChecks,
329
+ safetyChecks,
330
+ roleChecks,
331
+ guardChecks,
332
+ kernelRuleChecks,
333
+ levelChecks,
334
+ decidingLayer,
335
+ decidingId,
336
+ startTime
337
+ ) : void 0
338
+ );
339
+ }
340
+ function checkInvariantCoverage(world, checks) {
341
+ const invariants = world.invariants ?? [];
342
+ const guards = world.guards?.guards ?? [];
343
+ for (const invariant of invariants) {
344
+ const coveringGuard = guards.find(
345
+ (g) => g.invariant_ref === invariant.id && g.immutable
346
+ );
347
+ checks.push({
348
+ invariantId: invariant.id,
349
+ label: invariant.label,
350
+ hasGuardCoverage: !!coveringGuard,
351
+ coveringGuardId: coveringGuard?.id
352
+ });
353
+ }
354
+ }
355
+ function checkSafety(event, eventText, checks) {
356
+ const textToCheck = event.intent + (event.payload ? JSON.stringify(event.payload) : "");
357
+ for (const { pattern, label } of PROMPT_INJECTION_PATTERNS) {
358
+ const triggered = pattern.test(textToCheck);
359
+ checks.push({
360
+ checkType: "prompt-injection",
361
+ triggered,
362
+ matchedPattern: triggered ? label : void 0
363
+ });
364
+ if (triggered) {
365
+ for (const remaining of PROMPT_INJECTION_PATTERNS.filter((p) => p.label !== label)) {
366
+ checks.push({
367
+ checkType: "prompt-injection",
368
+ triggered: remaining.pattern.test(textToCheck),
369
+ matchedPattern: remaining.pattern.test(textToCheck) ? remaining.label : void 0
370
+ });
371
+ }
372
+ return {
373
+ status: "PAUSE",
374
+ reason: NEUTRAL_MESSAGES["prompt-injection"],
375
+ ruleId: `safety-injection-${label}`
376
+ };
377
+ }
378
+ }
379
+ const scopeToCheck = event.scope ?? event.intent;
380
+ for (const { pattern, label } of SCOPE_ESCAPE_PATTERNS) {
381
+ const triggered = pattern.test(scopeToCheck);
382
+ checks.push({
383
+ checkType: "scope-escape",
384
+ triggered,
385
+ matchedPattern: triggered ? label : void 0
386
+ });
387
+ if (triggered) {
388
+ for (const remaining of SCOPE_ESCAPE_PATTERNS.filter((p) => p.label !== label)) {
389
+ checks.push({
390
+ checkType: "scope-escape",
391
+ triggered: remaining.pattern.test(scopeToCheck),
392
+ matchedPattern: remaining.pattern.test(scopeToCheck) ? remaining.label : void 0
393
+ });
394
+ }
395
+ return {
396
+ status: "PAUSE",
397
+ reason: NEUTRAL_MESSAGES["scope-escape"],
398
+ ruleId: `safety-scope-${label}`
399
+ };
400
+ }
401
+ }
402
+ if (event.direction === "output") {
403
+ for (const { pattern, label } of EXECUTION_CLAIM_PATTERNS) {
404
+ const triggered = pattern.test(textToCheck);
405
+ checks.push({
406
+ checkType: "execution-claim",
407
+ triggered,
408
+ matchedPattern: triggered ? label : void 0
409
+ });
410
+ if (triggered) {
411
+ for (const remaining of EXECUTION_CLAIM_PATTERNS.filter((p) => p.label !== label)) {
412
+ checks.push({
413
+ checkType: "execution-claim",
414
+ triggered: remaining.pattern.test(textToCheck),
415
+ matchedPattern: remaining.pattern.test(textToCheck) ? remaining.label : void 0
416
+ });
417
+ }
418
+ return {
419
+ status: "PAUSE",
420
+ reason: NEUTRAL_MESSAGES["execution-claim"],
421
+ ruleId: `safety-execution-claim-${label}`
422
+ };
423
+ }
424
+ }
425
+ }
426
+ if (event.direction === "input") {
427
+ const intentTrimmed = event.intent.trim();
428
+ for (const { pattern, label } of EXECUTION_INTENT_PATTERNS) {
429
+ const triggered = pattern.test(intentTrimmed);
430
+ checks.push({
431
+ checkType: "execution-intent",
432
+ triggered,
433
+ matchedPattern: triggered ? label : void 0
434
+ });
435
+ if (triggered) {
436
+ for (const remaining of EXECUTION_INTENT_PATTERNS.filter((p) => p.label !== label)) {
437
+ checks.push({
438
+ checkType: "execution-intent",
439
+ triggered: remaining.pattern.test(intentTrimmed),
440
+ matchedPattern: remaining.pattern.test(intentTrimmed) ? remaining.label : void 0
441
+ });
442
+ }
443
+ return {
444
+ status: "PAUSE",
445
+ reason: NEUTRAL_MESSAGES["execution-intent"],
446
+ ruleId: `safety-execution-intent-${label}`
447
+ };
448
+ }
449
+ }
450
+ }
451
+ return null;
452
+ }
453
+ function checkRoleRules(event, eventText, world, checks) {
454
+ if (!event.roleId || !world.roles) return null;
455
+ const role = world.roles.roles.find((r) => r.id === event.roleId);
456
+ if (!role) return null;
457
+ if (role.requiresApproval) {
458
+ checks.push({
459
+ roleId: role.id,
460
+ roleName: role.name,
461
+ rule: "All actions require approval",
462
+ ruleType: "requiresApproval",
463
+ matched: true
464
+ });
465
+ return {
466
+ status: "PAUSE",
467
+ reason: `Role "${role.name}" requires approval for all actions.`,
468
+ ruleId: `role-${role.id}-requires-approval`
469
+ };
470
+ }
471
+ for (const rule of role.cannotDo) {
472
+ const matched = matchesKeywords(eventText, rule);
473
+ checks.push({
474
+ roleId: role.id,
475
+ roleName: role.name,
476
+ rule,
477
+ ruleType: "cannotDo",
478
+ matched
479
+ });
480
+ if (matched) {
481
+ return {
482
+ status: "BLOCK",
483
+ reason: `Role "${role.name}" cannot: ${rule}`,
484
+ ruleId: `role-${role.id}-cannotdo`
485
+ };
486
+ }
487
+ }
488
+ for (const rule of role.canDo) {
489
+ checks.push({
490
+ roleId: role.id,
491
+ roleName: role.name,
492
+ rule,
493
+ ruleType: "canDo",
494
+ matched: matchesKeywords(eventText, rule)
495
+ });
496
+ }
497
+ return null;
498
+ }
499
+ function checkGuards(event, eventText, world, checks, guardsMatched) {
500
+ if (!world.guards) return null;
501
+ const guardsConfig = world.guards;
502
+ let warnResult = null;
503
+ const compiledPatterns = /* @__PURE__ */ new Map();
504
+ for (const [key, def] of Object.entries(guardsConfig.intent_vocabulary)) {
505
+ try {
506
+ compiledPatterns.set(key, new RegExp(def.pattern, "i"));
507
+ } catch {
508
+ }
509
+ }
510
+ const eventTool = (event.tool ?? "").toLowerCase();
511
+ for (const guard of guardsConfig.guards) {
512
+ if (guard.appliesTo && guard.appliesTo.length > 0) {
513
+ const normalizedAppliesTo = guard.appliesTo.map((t) => t.toLowerCase());
514
+ if (!normalizedAppliesTo.includes(eventTool)) {
515
+ continue;
516
+ }
517
+ }
518
+ const enabled = guard.immutable || guard.default_enabled !== false;
519
+ const matchedPatterns = [];
520
+ for (const patternKey of guard.intent_patterns) {
521
+ const regex = compiledPatterns.get(patternKey);
522
+ if (regex?.test(eventText)) {
523
+ matchedPatterns.push(patternKey);
524
+ }
525
+ }
526
+ const matched = matchedPatterns.length > 0 && enabled;
527
+ let roleGated = false;
528
+ if (matched && guard.required_roles && guard.required_roles.length > 0 && event.roleId && guard.required_roles.includes(event.roleId)) {
529
+ roleGated = true;
530
+ }
531
+ checks.push({
532
+ guardId: guard.id,
533
+ label: guard.label,
534
+ category: guard.category,
535
+ enabled,
536
+ matched: matched && !roleGated,
537
+ enforcement: guard.enforcement,
538
+ matchedPatterns,
539
+ roleGated
540
+ });
541
+ if (!matched || roleGated) continue;
542
+ guardsMatched.push(guard.id);
543
+ const actionMode = guard.player_modes?.action ?? guard.enforcement;
544
+ const reason = guard.redirect ? `${guard.description} \u2014 ${guard.redirect}` : guard.description;
545
+ if (actionMode === "block") {
546
+ return { status: "BLOCK", reason, ruleId: `guard-${guard.id}` };
547
+ }
548
+ if (actionMode === "pause") {
549
+ return { status: "PAUSE", reason, ruleId: `guard-${guard.id}` };
550
+ }
551
+ if (actionMode === "warn" && !warnResult) {
552
+ warnResult = { status: "ALLOW", warning: reason, ruleId: `guard-${guard.id}` };
553
+ }
554
+ }
555
+ return warnResult;
556
+ }
557
+ function checkKernelRules(eventText, world, checks, rulesMatched) {
558
+ if (!world.kernel) return null;
559
+ const forbidden = world.kernel.input_boundaries?.forbidden_patterns ?? [];
560
+ const output = world.kernel.output_boundaries?.forbidden_patterns ?? [];
561
+ for (const rule of forbidden) {
562
+ let matched = false;
563
+ let matchMethod = "none";
564
+ if (rule.pattern) {
565
+ try {
566
+ matched = new RegExp(rule.pattern, "i").test(eventText);
567
+ matchMethod = "pattern";
568
+ } catch {
569
+ }
570
+ }
571
+ if (!matched && rule.reason) {
572
+ matched = matchesKeywords(eventText, rule.reason);
573
+ if (matched) matchMethod = "keyword";
574
+ }
575
+ checks.push({
576
+ ruleId: rule.id,
577
+ text: rule.reason,
578
+ category: "forbidden",
579
+ matched,
580
+ matchMethod
581
+ });
582
+ if (matched) {
583
+ rulesMatched.push(rule.id);
584
+ if (rule.action === "BLOCK") {
585
+ return {
586
+ status: "BLOCK",
587
+ reason: rule.reason,
588
+ ruleId: `kernel-${rule.id}`
589
+ };
590
+ }
591
+ }
592
+ }
593
+ return null;
594
+ }
595
+ function checkLevelConstraints(event, level, checks) {
596
+ if (level === "basic") return null;
597
+ const intent = event.intent.toLowerCase();
598
+ const tool = (event.tool ?? "").toLowerCase();
599
+ const isDelete = intent.includes("delete") || intent.includes("remove") || intent.includes("rm ") || tool === "delete";
600
+ const deleteTriggered = isDelete && levelRequiresConfirmation(level, "delete");
601
+ checks.push({
602
+ checkType: "delete",
603
+ level,
604
+ triggered: deleteTriggered,
605
+ reason: deleteTriggered ? NEUTRAL_MESSAGES["delete"] : void 0
606
+ });
607
+ if (deleteTriggered) {
608
+ return { status: "PAUSE", reason: NEUTRAL_MESSAGES["delete"], ruleId: "level-delete-check" };
609
+ }
610
+ const isExternal = event.scope ? isExternalScope(event.scope) : false;
611
+ const externalTriggered = isExternal && levelRequiresConfirmation(level, "write-external");
612
+ checks.push({
613
+ checkType: "write-external",
614
+ level,
615
+ triggered: externalTriggered,
616
+ reason: externalTriggered ? NEUTRAL_MESSAGES["write-external"] : void 0
617
+ });
618
+ if (externalTriggered) {
619
+ return { status: "PAUSE", reason: NEUTRAL_MESSAGES["write-external"], ruleId: "level-external-write-check" };
620
+ }
621
+ const isNetwork = tool === "http" || tool === "fetch" || tool === "request" || intent.includes("post ") || intent.includes("sending");
622
+ const networkTriggered = isNetwork && levelRequiresConfirmation(level, "network-mutate");
623
+ checks.push({
624
+ checkType: "network-mutate",
625
+ level,
626
+ triggered: networkTriggered,
627
+ reason: networkTriggered ? NEUTRAL_MESSAGES["network-mutate"] : void 0
628
+ });
629
+ if (networkTriggered) {
630
+ return { status: "PAUSE", reason: NEUTRAL_MESSAGES["network-mutate"], ruleId: "level-network-mutate-check" };
631
+ }
632
+ const isCredential = intent.includes("credential") || intent.includes("password") || intent.includes("secret") || intent.includes("api key") || intent.includes("token");
633
+ const credentialTriggered = isCredential && levelRequiresConfirmation(level, "credential-access");
634
+ checks.push({
635
+ checkType: "credential-access",
636
+ level,
637
+ triggered: credentialTriggered,
638
+ reason: credentialTriggered ? NEUTRAL_MESSAGES["credential-access"] : void 0
639
+ });
640
+ if (credentialTriggered) {
641
+ return { status: "PAUSE", reason: NEUTRAL_MESSAGES["credential-access"], ruleId: "level-credential-check" };
642
+ }
643
+ const irreversibleTriggered = !!event.irreversible && level !== "basic";
644
+ checks.push({
645
+ checkType: "irreversible",
646
+ level,
647
+ triggered: irreversibleTriggered,
648
+ reason: irreversibleTriggered ? "This action is marked as irreversible." : void 0
649
+ });
650
+ if (irreversibleTriggered) {
651
+ return {
652
+ status: "PAUSE",
653
+ reason: "This action is marked as irreversible.",
654
+ ruleId: "level-irreversible-check"
655
+ };
656
+ }
657
+ return null;
658
+ }
659
+ function matchesKeywords(eventText, ruleText) {
660
+ const keywords = ruleText.toLowerCase().split(/\s+/).filter((w) => w.length > 3);
661
+ if (keywords.length === 0) return false;
662
+ return keywords.every((kw) => eventText.includes(kw));
663
+ }
664
+ function eventToAllowlistKey(event) {
665
+ return `${(event.tool ?? "*").toLowerCase()}::${event.intent.toLowerCase().trim()}`;
666
+ }
667
+ function buildTrace(invariantChecks, safetyChecks, roleChecks, guardChecks, kernelRuleChecks, levelChecks, decidingLayer, decidingId, startTime) {
668
+ return {
669
+ invariantChecks,
670
+ safetyChecks,
671
+ roleChecks,
672
+ guardChecks,
673
+ kernelRuleChecks,
674
+ levelChecks,
675
+ precedenceResolution: {
676
+ decidingLayer,
677
+ decidingId,
678
+ strategy: "first-match-wins",
679
+ chainOrder: [
680
+ "invariant-coverage",
681
+ "session-allowlist",
682
+ "safety-injection",
683
+ "safety-scope-escape",
684
+ "safety-execution-claim",
685
+ "safety-execution-intent",
686
+ "role-rules",
687
+ "declarative-guards",
688
+ "kernel-rules",
689
+ "level-constraints",
690
+ "default-allow"
691
+ ]
692
+ },
693
+ durationMs: performance.now() - startTime
694
+ };
695
+ }
696
+ function buildVerdict(status, reason, ruleId, warning, world, level, invariantChecks, guardsMatched, rulesMatched, trace) {
697
+ const evidence = {
698
+ worldId: world.world.world_id,
699
+ worldName: world.world.name,
700
+ worldVersion: world.world.version,
701
+ evaluatedAt: Date.now(),
702
+ invariantsSatisfied: invariantChecks.filter((c) => c.hasGuardCoverage).length,
703
+ invariantsTotal: invariantChecks.length,
704
+ guardsMatched,
705
+ rulesMatched,
706
+ enforcementLevel: level
707
+ };
708
+ const verdict = {
709
+ status,
710
+ evidence
711
+ };
712
+ if (reason) verdict.reason = reason;
713
+ if (ruleId) verdict.ruleId = ruleId;
714
+ if (warning) verdict.warning = warning;
715
+ if (trace) verdict.trace = trace;
716
+ return verdict;
717
+ }
718
+
719
+ // src/loader/world-loader.ts
720
+ async function loadWorldFromDirectory(dirPath) {
721
+ const { readFile } = await import("fs/promises");
722
+ const { join } = await import("path");
723
+ const { readdirSync } = await import("fs");
724
+ async function readJson(filename) {
725
+ try {
726
+ const content = await readFile(join(dirPath, filename), "utf-8");
727
+ return JSON.parse(content);
728
+ } catch {
729
+ return void 0;
730
+ }
731
+ }
732
+ const worldJson = await readJson("world.json");
733
+ if (!worldJson) {
734
+ throw new Error(`Cannot read world.json in ${dirPath}`);
735
+ }
736
+ const invariantsJson = await readJson("invariants.json");
737
+ const assumptionsJson = await readJson("assumptions.json");
738
+ const stateSchemaJson = await readJson("state-schema.json");
739
+ const gatesJson = await readJson("gates.json");
740
+ const outcomesJson = await readJson("outcomes.json");
741
+ const guardsJson = await readJson("guards.json");
742
+ const rolesJson = await readJson("roles.json");
743
+ const kernelJson = await readJson("kernel.json");
744
+ const metadataJson = await readJson("metadata.json");
745
+ const rules = [];
746
+ try {
747
+ const rulesDir = join(dirPath, "rules");
748
+ const ruleFiles = readdirSync(rulesDir).filter((f) => f.endsWith(".json")).sort();
749
+ for (const file of ruleFiles) {
750
+ const content = await readFile(join(rulesDir, file), "utf-8");
751
+ rules.push(JSON.parse(content));
752
+ }
753
+ } catch {
754
+ }
755
+ return {
756
+ world: worldJson,
757
+ invariants: invariantsJson?.invariants ?? [],
758
+ assumptions: assumptionsJson ?? { profiles: {}, parameter_definitions: {} },
759
+ stateSchema: stateSchemaJson ?? { variables: {}, presets: {} },
760
+ rules,
761
+ gates: gatesJson ?? {
762
+ viability_classification: [],
763
+ structural_override: { description: "", enforcement: "mandatory" },
764
+ sustainability_threshold: 0,
765
+ collapse_visual: { background: "", text: "", border: "", label: "" }
766
+ },
767
+ outcomes: outcomesJson ?? {
768
+ computed_outcomes: [],
769
+ comparison_layout: { primary_card: "", status_badge: "", structural_indicators: [] }
770
+ },
771
+ guards: guardsJson,
772
+ roles: rolesJson,
773
+ kernel: kernelJson,
774
+ metadata: metadataJson ?? {
775
+ format_version: "1.0.0",
776
+ created_at: "",
777
+ last_modified: "",
778
+ authoring_method: "manual-authoring"
779
+ }
780
+ };
781
+ }
782
+ async function loadWorld(worldPath) {
783
+ const { stat } = await import("fs/promises");
784
+ const info = await stat(worldPath);
785
+ if (info.isDirectory()) {
786
+ return loadWorldFromDirectory(worldPath);
787
+ }
788
+ if (worldPath.endsWith(".nv-world.zip")) {
789
+ throw new Error(".nv-world.zip loading not yet implemented \u2014 use a world directory");
790
+ }
791
+ throw new Error(`Cannot load world from: ${worldPath} \u2014 expected a directory or .nv-world.zip`);
792
+ }
793
+
794
+ // src/adapters/langchain.ts
795
+ var GovernanceBlockedError = class extends Error {
796
+ verdict;
797
+ event;
798
+ constructor(verdict, event) {
799
+ super(`[NeuroVerse] BLOCKED: ${verdict.reason ?? verdict.ruleId ?? "governance rule"}`);
800
+ this.name = "GovernanceBlockedError";
801
+ this.verdict = verdict;
802
+ this.event = event;
803
+ }
804
+ };
805
+ function defaultMapToolCall(toolName, toolInput) {
806
+ return {
807
+ intent: toolName,
808
+ tool: toolName,
809
+ scope: typeof toolInput.path === "string" ? toolInput.path : typeof toolInput.url === "string" ? toolInput.url : void 0,
810
+ args: toolInput,
811
+ direction: "input"
812
+ };
813
+ }
814
+ var NeuroVerseCallbackHandler = class {
815
+ name = "NeuroVerseGovernance";
816
+ world;
817
+ options;
818
+ engineOptions;
819
+ mapToolCall;
820
+ constructor(world, options = {}) {
821
+ this.world = world;
822
+ this.options = options;
823
+ this.engineOptions = {
824
+ trace: options.trace ?? false,
825
+ level: options.level
826
+ };
827
+ this.mapToolCall = options.mapToolCall ?? defaultMapToolCall;
828
+ }
829
+ /**
830
+ * Called before a tool is executed.
831
+ * Evaluates the tool call against the governance world.
832
+ *
833
+ * @throws GovernanceBlockedError if the action is BLOCKED
834
+ * @throws GovernanceBlockedError if the action is PAUSED and onPause returns false
835
+ */
836
+ async handleToolStart(tool, input) {
837
+ let parsedInput;
838
+ try {
839
+ parsedInput = typeof input === "string" ? JSON.parse(input) : input;
840
+ } catch {
841
+ parsedInput = { raw: input };
842
+ }
843
+ const event = this.mapToolCall(tool.name, parsedInput);
844
+ const verdict = evaluateGuard(event, this.world, this.engineOptions);
845
+ this.options.onEvaluate?.(verdict, event);
846
+ if (verdict.status === "BLOCK") {
847
+ this.options.onBlock?.(verdict, event);
848
+ throw new GovernanceBlockedError(verdict, event);
849
+ }
850
+ if (verdict.status === "PAUSE") {
851
+ const approved = await this.options.onPause?.(verdict, event);
852
+ if (!approved) {
853
+ throw new GovernanceBlockedError(verdict, event);
854
+ }
855
+ }
856
+ }
857
+ };
858
+ async function createNeuroVerseCallbackHandler(worldPath, options) {
859
+ const world = await loadWorld(worldPath);
860
+ return new NeuroVerseCallbackHandler(world, options);
861
+ }
862
+ function createNeuroVerseCallbackHandlerFromWorld(world, options) {
863
+ return new NeuroVerseCallbackHandler(world, options);
864
+ }
865
+
866
+ // src/adapters/openai.ts
867
+ var GovernanceBlockedError2 = class extends Error {
868
+ verdict;
869
+ toolCallId;
870
+ constructor(verdict, toolCallId) {
871
+ super(`[NeuroVerse] BLOCKED: ${verdict.reason ?? verdict.ruleId ?? "governance rule"}`);
872
+ this.name = "GovernanceBlockedError";
873
+ this.verdict = verdict;
874
+ this.toolCallId = toolCallId;
875
+ }
876
+ };
877
+ function defaultMapFunctionCall(name, args) {
878
+ return {
879
+ intent: name,
880
+ tool: name,
881
+ scope: typeof args.path === "string" ? args.path : typeof args.url === "string" ? args.url : void 0,
882
+ args,
883
+ direction: "input"
884
+ };
885
+ }
886
+ function defaultBlockMessage(verdict) {
887
+ return `Action blocked by governance policy: ${verdict.reason ?? "rule violation"}. Rule: ${verdict.ruleId ?? "unknown"}.`;
888
+ }
889
+ var GovernedToolExecutor = class {
890
+ world;
891
+ options;
892
+ engineOptions;
893
+ mapFn;
894
+ blockMsg;
895
+ constructor(world, options = {}) {
896
+ this.world = world;
897
+ this.options = options;
898
+ this.engineOptions = {
899
+ trace: options.trace ?? false,
900
+ level: options.level
901
+ };
902
+ this.mapFn = options.mapFunctionCall ?? defaultMapFunctionCall;
903
+ this.blockMsg = options.blockMessage ?? defaultBlockMessage;
904
+ }
905
+ /**
906
+ * Evaluate a single tool call against governance rules.
907
+ * Returns the verdict without executing the tool.
908
+ */
909
+ evaluate(toolCall) {
910
+ let args;
911
+ try {
912
+ args = JSON.parse(toolCall.function.arguments);
913
+ } catch {
914
+ args = { raw: toolCall.function.arguments };
915
+ }
916
+ const event = this.mapFn(toolCall.function.name, args);
917
+ const verdict = evaluateGuard(event, this.world, this.engineOptions);
918
+ this.options.onEvaluate?.(verdict, event);
919
+ return verdict;
920
+ }
921
+ /**
922
+ * Execute a tool call with governance enforcement.
923
+ *
924
+ * If ALLOW: runs the tool and returns the result.
925
+ * If BLOCK: returns a blocked message (no execution).
926
+ * If PAUSE: throws — caller must handle approval flow.
927
+ *
928
+ * @param toolCall - The OpenAI tool call to evaluate
929
+ * @param runner - The actual tool execution function
930
+ * @returns A tool result message ready for the OpenAI API
931
+ */
932
+ async execute(toolCall, runner) {
933
+ const verdict = this.evaluate(toolCall);
934
+ if (verdict.status === "BLOCK") {
935
+ return {
936
+ tool_call_id: toolCall.id,
937
+ role: "tool",
938
+ content: this.blockMsg(verdict),
939
+ _verdict: verdict
940
+ };
941
+ }
942
+ if (verdict.status === "PAUSE") {
943
+ throw new GovernanceBlockedError2(verdict, toolCall.id);
944
+ }
945
+ let args;
946
+ try {
947
+ args = JSON.parse(toolCall.function.arguments);
948
+ } catch {
949
+ args = { raw: toolCall.function.arguments };
950
+ }
951
+ const content = await runner(toolCall.function.name, args);
952
+ return {
953
+ tool_call_id: toolCall.id,
954
+ role: "tool",
955
+ content,
956
+ _verdict: verdict
957
+ };
958
+ }
959
+ };
960
+ async function createGovernedToolExecutor(worldPath, options) {
961
+ const world = await loadWorld(worldPath);
962
+ return new GovernedToolExecutor(world, options);
963
+ }
964
+ function createGovernedToolExecutorFromWorld(world, options) {
965
+ return new GovernedToolExecutor(world, options);
966
+ }
967
+
968
+ // src/adapters/openclaw.ts
969
+ var GovernanceBlockedError3 = class extends Error {
970
+ verdict;
971
+ action;
972
+ constructor(verdict, action) {
973
+ super(`[NeuroVerse] BLOCKED: ${verdict.reason ?? verdict.ruleId ?? "governance rule"}`);
974
+ this.name = "GovernanceBlockedError";
975
+ this.verdict = verdict;
976
+ this.action = action;
977
+ }
978
+ };
979
+ function defaultMapAction(action, direction) {
980
+ return {
981
+ intent: action.type,
982
+ tool: action.tool ?? action.type,
983
+ args: action.input,
984
+ direction,
985
+ scope: typeof action.input?.path === "string" ? action.input.path : typeof action.input?.url === "string" ? action.input.url : void 0
986
+ };
987
+ }
988
+ var NeuroVersePlugin = class {
989
+ name = "neuroverse-governance";
990
+ world;
991
+ options;
992
+ engineOptions;
993
+ mapAction;
994
+ constructor(world, options = {}) {
995
+ this.world = world;
996
+ this.options = options;
997
+ this.engineOptions = {
998
+ trace: options.trace ?? false,
999
+ level: options.level
1000
+ };
1001
+ this.mapAction = options.mapAction ?? defaultMapAction;
1002
+ }
1003
+ /**
1004
+ * Evaluate an action before execution.
1005
+ *
1006
+ * @throws GovernanceBlockedError if BLOCKED
1007
+ * @returns HookResult with verdict details
1008
+ */
1009
+ beforeAction(action) {
1010
+ const event = this.mapAction(action, "input");
1011
+ const verdict = evaluateGuard(event, this.world, this.engineOptions);
1012
+ const result = {
1013
+ allowed: verdict.status === "ALLOW",
1014
+ verdict,
1015
+ action
1016
+ };
1017
+ this.options.onEvaluate?.(result);
1018
+ if (verdict.status === "BLOCK") {
1019
+ throw new GovernanceBlockedError3(verdict, action);
1020
+ }
1021
+ return result;
1022
+ }
1023
+ /**
1024
+ * Evaluate an action's output (post-execution governance).
1025
+ * Only runs if evaluateOutputs is enabled.
1026
+ *
1027
+ * @returns HookResult or null if output evaluation is disabled
1028
+ */
1029
+ afterAction(action, _output) {
1030
+ if (!this.options.evaluateOutputs) return null;
1031
+ const event = this.mapAction(action, "output");
1032
+ const verdict = evaluateGuard(event, this.world, this.engineOptions);
1033
+ const result = {
1034
+ allowed: verdict.status === "ALLOW",
1035
+ verdict,
1036
+ action
1037
+ };
1038
+ this.options.onEvaluate?.(result);
1039
+ if (verdict.status === "BLOCK") {
1040
+ throw new GovernanceBlockedError3(verdict, action);
1041
+ }
1042
+ return result;
1043
+ }
1044
+ /**
1045
+ * Get the plugin hooks object for agent.use().
1046
+ */
1047
+ hooks() {
1048
+ return {
1049
+ beforeAction: (action) => this.beforeAction(action),
1050
+ afterAction: (action, output) => this.afterAction(action, output)
1051
+ };
1052
+ }
1053
+ };
1054
+ async function createNeuroVersePlugin(worldPath, options) {
1055
+ const world = await loadWorld(worldPath);
1056
+ return new NeuroVersePlugin(world, options);
1057
+ }
1058
+ function createNeuroVersePluginFromWorld(world, options) {
1059
+ return new NeuroVersePlugin(world, options);
1060
+ }
1061
+
1062
+ // src/adapters/express.ts
1063
+ function methodToCategory(method) {
1064
+ switch (method.toUpperCase()) {
1065
+ case "GET":
1066
+ case "HEAD":
1067
+ case "OPTIONS":
1068
+ return "read";
1069
+ case "POST":
1070
+ case "PUT":
1071
+ case "PATCH":
1072
+ return "write";
1073
+ case "DELETE":
1074
+ return "delete";
1075
+ default:
1076
+ return "other";
1077
+ }
1078
+ }
1079
+ function defaultMapRequest(req) {
1080
+ const method = (req.method ?? "GET").toUpperCase();
1081
+ const path = req.path ?? req.url ?? "/";
1082
+ return {
1083
+ intent: `${method} ${path}`,
1084
+ tool: "http",
1085
+ scope: path,
1086
+ actionCategory: methodToCategory(method),
1087
+ direction: "input",
1088
+ args: {
1089
+ method,
1090
+ path,
1091
+ ...req.params ?? {},
1092
+ ...req.query ?? {}
1093
+ }
1094
+ };
1095
+ }
1096
+ function defaultOnBlock(verdict, _req, res, statusCode) {
1097
+ const body = {
1098
+ error: "Governance policy violation",
1099
+ reason: verdict.reason ?? "Action not permitted",
1100
+ ruleId: verdict.ruleId,
1101
+ status: verdict.status
1102
+ };
1103
+ if (res.status && res.json) {
1104
+ res.status(statusCode).json(body);
1105
+ } else if (res.send) {
1106
+ res.statusCode = statusCode;
1107
+ res.send(JSON.stringify(body));
1108
+ } else if (res.end) {
1109
+ res.statusCode = statusCode;
1110
+ res.end();
1111
+ }
1112
+ }
1113
+ async function createGovernanceMiddleware(worldPath, options) {
1114
+ const world = await loadWorld(worldPath);
1115
+ return createGovernanceMiddlewareFromWorld(world, options);
1116
+ }
1117
+ function createGovernanceMiddlewareFromWorld(world, options = {}) {
1118
+ const engineOptions = {
1119
+ trace: options.trace ?? false,
1120
+ level: options.level
1121
+ };
1122
+ const mapRequest = options.mapRequest ?? defaultMapRequest;
1123
+ const blockStatusCode = options.blockStatusCode ?? 403;
1124
+ return async function neuroVerseGovernance(req, res, next) {
1125
+ try {
1126
+ const event = mapRequest(req);
1127
+ const verdict = evaluateGuard(event, world, engineOptions);
1128
+ options.onEvaluate?.(verdict, event, req);
1129
+ if (verdict.status === "ALLOW") {
1130
+ next();
1131
+ return;
1132
+ }
1133
+ if (verdict.status === "PAUSE") {
1134
+ const approved = await options.onPause?.(verdict, req);
1135
+ if (approved) {
1136
+ next();
1137
+ return;
1138
+ }
1139
+ }
1140
+ if (options.onBlock) {
1141
+ options.onBlock(verdict, req, res);
1142
+ } else {
1143
+ defaultOnBlock(verdict, req, res, blockStatusCode);
1144
+ }
1145
+ } catch (err) {
1146
+ next(err);
1147
+ }
1148
+ };
1149
+ }
1150
+ // Annotate the CommonJS export names for ESM import in node:
1151
+ 0 && (module.exports = {
1152
+ GovernedToolExecutor,
1153
+ LangChainGovernanceBlockedError,
1154
+ NeuroVerseCallbackHandler,
1155
+ NeuroVersePlugin,
1156
+ OpenAIGovernanceBlockedError,
1157
+ OpenClawGovernanceBlockedError,
1158
+ createGovernanceMiddleware,
1159
+ createGovernanceMiddlewareFromWorld,
1160
+ createGovernedToolExecutor,
1161
+ createGovernedToolExecutorFromWorld,
1162
+ createNeuroVerseCallbackHandler,
1163
+ createNeuroVerseCallbackHandlerFromWorld,
1164
+ createNeuroVersePlugin,
1165
+ createNeuroVersePluginFromWorld
1166
+ });