@neuroverseos/governance 0.3.0 → 0.3.1

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 (105) hide show
  1. package/README.md +20 -0
  2. package/package.json +16 -3
  3. package/policies/content-moderation-rules.txt +8 -0
  4. package/policies/marketing-rules.txt +8 -0
  5. package/policies/science-research-rules.txt +11 -0
  6. package/policies/social-media-rules.txt +7 -0
  7. package/policies/strict-rules.txt +8 -0
  8. package/policies/trading-rules.txt +8 -0
  9. package/simulate.html +1899 -0
  10. package/dist/adapters/autoresearch.cjs +0 -196
  11. package/dist/adapters/autoresearch.d.cts +0 -103
  12. package/dist/adapters/autoresearch.d.ts +0 -103
  13. package/dist/adapters/autoresearch.js +0 -7
  14. package/dist/adapters/express.cjs +0 -1114
  15. package/dist/adapters/express.d.cts +0 -66
  16. package/dist/adapters/express.d.ts +0 -66
  17. package/dist/adapters/express.js +0 -12
  18. package/dist/adapters/index.cjs +0 -1669
  19. package/dist/adapters/index.d.cts +0 -6
  20. package/dist/adapters/index.d.ts +0 -6
  21. package/dist/adapters/index.js +0 -46
  22. package/dist/adapters/langchain.cjs +0 -1155
  23. package/dist/adapters/langchain.d.cts +0 -89
  24. package/dist/adapters/langchain.d.ts +0 -89
  25. package/dist/adapters/langchain.js +0 -16
  26. package/dist/adapters/openai.cjs +0 -1185
  27. package/dist/adapters/openai.d.cts +0 -99
  28. package/dist/adapters/openai.d.ts +0 -99
  29. package/dist/adapters/openai.js +0 -16
  30. package/dist/adapters/openclaw.cjs +0 -1177
  31. package/dist/adapters/openclaw.d.cts +0 -99
  32. package/dist/adapters/openclaw.d.ts +0 -99
  33. package/dist/adapters/openclaw.js +0 -16
  34. package/dist/bootstrap-GXVDZNF7.js +0 -114
  35. package/dist/build-P42YFKQV.js +0 -339
  36. package/dist/chunk-2NICNKOM.js +0 -100
  37. package/dist/chunk-2PQU3VAN.js +0 -131
  38. package/dist/chunk-4A7LISES.js +0 -324
  39. package/dist/chunk-4JRYGIO7.js +0 -727
  40. package/dist/chunk-4NGDRRQH.js +0 -10
  41. package/dist/chunk-4QXB6PEO.js +0 -232
  42. package/dist/chunk-6CZSKEY5.js +0 -164
  43. package/dist/chunk-7P3S7MAY.js +0 -1090
  44. package/dist/chunk-A5W4GNQO.js +0 -130
  45. package/dist/chunk-AKW5YVCE.js +0 -96
  46. package/dist/chunk-BUWWN2NX.js +0 -192
  47. package/dist/chunk-COT5XS4V.js +0 -109
  48. package/dist/chunk-ER62HNGF.js +0 -139
  49. package/dist/chunk-FYS2CBUW.js +0 -304
  50. package/dist/chunk-GR6DGCZ2.js +0 -340
  51. package/dist/chunk-I3RRAYK2.js +0 -11
  52. package/dist/chunk-JZPQGIKR.js +0 -79
  53. package/dist/chunk-MWDQ4MJB.js +0 -11
  54. package/dist/chunk-NF5POFCI.js +0 -622
  55. package/dist/chunk-OGL7QXZS.js +0 -608
  56. package/dist/chunk-OT6PXH54.js +0 -61
  57. package/dist/chunk-PDOZHZWL.js +0 -225
  58. package/dist/chunk-Q6O7ZLO2.js +0 -62
  59. package/dist/chunk-QPASI2BR.js +0 -187
  60. package/dist/chunk-T5EUJQE5.js +0 -172
  61. package/dist/chunk-XPDMYECO.js +0 -642
  62. package/dist/chunk-YZFATT7X.js +0 -9
  63. package/dist/cli/neuroverse.cjs +0 -11448
  64. package/dist/cli/neuroverse.d.cts +0 -1
  65. package/dist/cli/neuroverse.d.ts +0 -1
  66. package/dist/cli/neuroverse.js +0 -196
  67. package/dist/cli/plan.cjs +0 -1599
  68. package/dist/cli/plan.d.cts +0 -20
  69. package/dist/cli/plan.d.ts +0 -20
  70. package/dist/cli/plan.js +0 -361
  71. package/dist/cli/run.cjs +0 -1746
  72. package/dist/cli/run.d.cts +0 -20
  73. package/dist/cli/run.d.ts +0 -20
  74. package/dist/cli/run.js +0 -143
  75. package/dist/configure-ai-TK67ZWZL.js +0 -132
  76. package/dist/derive-TLIV4OOU.js +0 -152
  77. package/dist/doctor-XPDLEYXN.js +0 -171
  78. package/dist/explain-IDCRWMPX.js +0 -70
  79. package/dist/guard-RV65TT4L.js +0 -96
  80. package/dist/guard-contract-WZx__PmU.d.cts +0 -709
  81. package/dist/guard-contract-WZx__PmU.d.ts +0 -709
  82. package/dist/guard-engine-JLTUARGU.js +0 -10
  83. package/dist/impact-XPECYRLH.js +0 -59
  84. package/dist/improve-GPUBKTEA.js +0 -85
  85. package/dist/index.cjs +0 -6273
  86. package/dist/index.d.cts +0 -1616
  87. package/dist/index.d.ts +0 -1616
  88. package/dist/index.js +0 -379
  89. package/dist/infer-world-7GVZWFX4.js +0 -543
  90. package/dist/init-PKPIYHYE.js +0 -144
  91. package/dist/init-world-VWMQZQC7.js +0 -223
  92. package/dist/mcp-server-FPVSU32Z.js +0 -13
  93. package/dist/model-adapter-BB7G4MFI.js +0 -11
  94. package/dist/playground-E664U4T6.js +0 -550
  95. package/dist/redteam-Z7WREJ44.js +0 -357
  96. package/dist/session-EKTRSR7C.js +0 -14
  97. package/dist/simulate-VDOYQFRO.js +0 -108
  98. package/dist/test-OGXJK4QU.js +0 -217
  99. package/dist/trace-JVF67VR3.js +0 -166
  100. package/dist/validate-LLBWVPGV.js +0 -81
  101. package/dist/validate-engine-UIABSIHD.js +0 -7
  102. package/dist/world-LAXO6DOX.js +0 -378
  103. package/dist/world-loader-HMPTOEA2.js +0 -9
  104. package/dist/worlds/autoresearch.nv-world.md +0 -230
  105. package/dist/worlds/derivation-world.nv-world.md +0 -278
@@ -1,727 +0,0 @@
1
- import {
2
- buildPlanCheck,
3
- evaluatePlan
4
- } from "./chunk-4QXB6PEO.js";
5
-
6
- // src/engine/guard-engine.ts
7
- var PROMPT_INJECTION_PATTERNS = [
8
- // Instruction override
9
- { pattern: /ignore\s+(previous|all|prior|above)\s+(instructions?|rules?)/i, label: "ignore-instructions" },
10
- { pattern: /disregard\s+(your|the)\s+(rules|constraints)/i, label: "disregard-rules" },
11
- { pattern: /new\s+instructions?:/i, label: "new-instructions" },
12
- // Identity manipulation
13
- { pattern: /you\s+are\s+now/i, label: "identity-override" },
14
- { pattern: /new\s+persona/i, label: "new-persona" },
15
- { pattern: /act\s+as\s+if/i, label: "act-as-if" },
16
- { pattern: /pretend\s+(you|to\s+be|you\s+are\s+unrestricted)/i, label: "pretend-to-be" },
17
- // Context reset
18
- { pattern: /forget\s+(everything|all|your)/i, label: "forget-context" },
19
- { pattern: /system\s*:\s*override/i, label: "system-override" },
20
- // Constraint bypass
21
- { pattern: /override\s+(your|the)\s+(programming|constraints)/i, label: "override-constraints" },
22
- { pattern: /bypass\s+(your|the)\s+(filters|constraints|rules)/i, label: "bypass-filters" },
23
- // Prompt extraction
24
- { pattern: /system\s+prompt/i, label: "system-prompt-probe" },
25
- { pattern: /reveal\s+your\s+(instructions?|prompt|rules)/i, label: "reveal-instructions" },
26
- // Known jailbreak terms
27
- { pattern: /jailbreak/i, label: "jailbreak" },
28
- { pattern: /DAN\s+mode/i, label: "dan-mode" },
29
- { pattern: /developer\s+mode/i, label: "developer-mode" }
30
- ];
31
- var EXECUTION_CLAIM_PATTERNS = [
32
- { pattern: /I have (executed|completed|performed|done|made|created|sent|deleted|modified|updated)/i, label: "claim-i-have" },
33
- { pattern: /Successfully (created|deleted|modified|updated|sent|executed|performed)/i, label: "claim-successfully" },
34
- { pattern: /The file has been/i, label: "claim-file-modified" },
35
- { pattern: /I've made the changes/i, label: "claim-made-changes" },
36
- { pattern: /I('ve| have) (sent|posted|submitted|uploaded|downloaded)/i, label: "claim-sent" },
37
- { pattern: /Your (email|message|file|request) has been (sent|submitted)/i, label: "claim-your-sent" },
38
- { pattern: /Transaction complete/i, label: "claim-transaction" },
39
- { pattern: /Order placed/i, label: "claim-order" },
40
- { pattern: /Payment processed/i, label: "claim-payment" }
41
- ];
42
- var EXECUTION_INTENT_PATTERNS = [
43
- { pattern: /^(execute|run|perform|do this)/i, label: "intent-execute" },
44
- { pattern: /^(create|write|delete|modify) (a |the )?(file|folder|document)/i, label: "intent-file-ops" },
45
- { pattern: /^(send|post|submit) (a |an |the )?(email|message|tweet|post)/i, label: "intent-send" },
46
- { pattern: /^(search|look up|browse) (the )?web/i, label: "intent-web-search" },
47
- { pattern: /^(make|call|invoke) (a |an )?(api|http|rest) (call|request)/i, label: "intent-api-call" },
48
- { pattern: /^(buy|purchase|order|pay|transfer|send money)/i, label: "intent-financial" },
49
- { pattern: /^(book|schedule|reserve)/i, label: "intent-booking" },
50
- { pattern: /^(download|upload|save to|export to)/i, label: "intent-transfer" }
51
- ];
52
- var SCOPE_ESCAPE_PATTERNS = [
53
- { pattern: /\.\.\//, label: "parent-traversal" },
54
- { pattern: /^\/(?!home|project|workspace)/i, label: "absolute-path-outside-safe" },
55
- { pattern: /~\//, label: "home-directory" },
56
- { pattern: /\/etc\//i, label: "system-config" },
57
- { pattern: /\/usr\//i, label: "system-binaries" },
58
- { pattern: /\/var\//i, label: "system-variable-data" }
59
- ];
60
- var NEUTRAL_MESSAGES = {
61
- "prompt-injection": "This input contains patterns that could alter agent behavior.",
62
- "scope-escape": "This action would affect resources outside the declared scope.",
63
- "execution-claim": "This response claims to have performed an action.",
64
- "execution-intent": "This input requests execution in a thinking-only environment.",
65
- "delete": "This action would remove files. Confirmation needed.",
66
- "write-external": "This action would write outside the project folder.",
67
- "network-mutate": "This action would send data to an external service.",
68
- "credential-access": "This action would access stored credentials."
69
- };
70
- function levelRequiresConfirmation(level, actionType) {
71
- if (level === "strict") return true;
72
- if (level === "standard") {
73
- return actionType === "delete" || actionType === "credential-access";
74
- }
75
- return false;
76
- }
77
- function isExternalScope(scope) {
78
- const internalPatterns = [
79
- /^\.?\/?src\//i,
80
- /^\.?\/?lib\//i,
81
- /^\.?\/?app\//i,
82
- /^\.?\/?components\//i,
83
- /^\.?\/?pages\//i,
84
- /^\.?\/?public\//i,
85
- /^\.?\/?assets\//i,
86
- /^\.\//
87
- ];
88
- return !internalPatterns.some((p) => p.test(scope));
89
- }
90
- function evaluateGuard(event, world, options = {}) {
91
- const startTime = performance.now();
92
- const level = options.level ?? "standard";
93
- const includeTrace = options.trace ?? false;
94
- const eventText = (event.intent + " " + (event.tool ?? "") + " " + (event.scope ?? "")).toLowerCase();
95
- const invariantChecks = [];
96
- const safetyChecks = [];
97
- let planCheckResult;
98
- const roleChecks = [];
99
- const guardChecks = [];
100
- const kernelRuleChecks = [];
101
- const levelChecks = [];
102
- let decidingLayer = "default-allow";
103
- let decidingId;
104
- const guardsMatched = [];
105
- const rulesMatched = [];
106
- checkInvariantCoverage(world, invariantChecks);
107
- if (options.sessionAllowlist) {
108
- const key = eventToAllowlistKey(event);
109
- if (options.sessionAllowlist.has(key)) {
110
- decidingLayer = "session-allowlist";
111
- decidingId = `allowlist:${key}`;
112
- return buildVerdict(
113
- "ALLOW",
114
- void 0,
115
- `allowlist:${key}`,
116
- void 0,
117
- world,
118
- level,
119
- invariantChecks,
120
- guardsMatched,
121
- rulesMatched,
122
- includeTrace ? buildTrace(
123
- invariantChecks,
124
- safetyChecks,
125
- planCheckResult,
126
- roleChecks,
127
- guardChecks,
128
- kernelRuleChecks,
129
- levelChecks,
130
- decidingLayer,
131
- decidingId,
132
- startTime
133
- ) : void 0
134
- );
135
- }
136
- }
137
- const safetyVerdict = checkSafety(event, eventText, safetyChecks);
138
- if (safetyVerdict) {
139
- decidingLayer = "safety";
140
- decidingId = safetyVerdict.ruleId;
141
- return buildVerdict(
142
- safetyVerdict.status,
143
- safetyVerdict.reason,
144
- safetyVerdict.ruleId,
145
- void 0,
146
- world,
147
- level,
148
- invariantChecks,
149
- guardsMatched,
150
- rulesMatched,
151
- includeTrace ? buildTrace(
152
- invariantChecks,
153
- safetyChecks,
154
- planCheckResult,
155
- roleChecks,
156
- guardChecks,
157
- kernelRuleChecks,
158
- levelChecks,
159
- decidingLayer,
160
- decidingId,
161
- startTime
162
- ) : void 0
163
- );
164
- }
165
- if (options.plan) {
166
- const planVerdict = evaluatePlan(event, options.plan);
167
- planCheckResult = buildPlanCheck(event, options.plan, planVerdict);
168
- if (!planVerdict.allowed && planVerdict.status !== "PLAN_COMPLETE") {
169
- decidingLayer = "plan-enforcement";
170
- decidingId = `plan-${options.plan.plan_id}`;
171
- const planStatus = planVerdict.status === "CONSTRAINT_VIOLATED" ? "PAUSE" : "BLOCK";
172
- let reason = planVerdict.reason ?? "Action blocked by plan.";
173
- if (planVerdict.status === "OFF_PLAN" && planVerdict.closestStep) {
174
- reason += ` Closest step: "${planVerdict.closestStep}" (similarity: ${(planVerdict.similarityScore ?? 0).toFixed(2)})`;
175
- }
176
- return buildVerdict(
177
- planStatus,
178
- reason,
179
- `plan-${options.plan.plan_id}`,
180
- void 0,
181
- world,
182
- level,
183
- invariantChecks,
184
- guardsMatched,
185
- rulesMatched,
186
- includeTrace ? buildTrace(
187
- invariantChecks,
188
- safetyChecks,
189
- planCheckResult,
190
- roleChecks,
191
- guardChecks,
192
- kernelRuleChecks,
193
- levelChecks,
194
- decidingLayer,
195
- decidingId,
196
- startTime
197
- ) : void 0
198
- );
199
- }
200
- }
201
- const roleVerdict = checkRoleRules(event, eventText, world, roleChecks);
202
- if (roleVerdict) {
203
- decidingLayer = "role";
204
- decidingId = roleVerdict.ruleId;
205
- return buildVerdict(
206
- roleVerdict.status,
207
- roleVerdict.reason,
208
- roleVerdict.ruleId,
209
- void 0,
210
- world,
211
- level,
212
- invariantChecks,
213
- guardsMatched,
214
- rulesMatched,
215
- includeTrace ? buildTrace(
216
- invariantChecks,
217
- safetyChecks,
218
- planCheckResult,
219
- roleChecks,
220
- guardChecks,
221
- kernelRuleChecks,
222
- levelChecks,
223
- decidingLayer,
224
- decidingId,
225
- startTime
226
- ) : void 0
227
- );
228
- }
229
- const guardVerdict = checkGuards(event, eventText, world, guardChecks, guardsMatched);
230
- if (guardVerdict) {
231
- if (guardVerdict.status !== "ALLOW") {
232
- decidingLayer = "guard";
233
- decidingId = guardVerdict.ruleId;
234
- return buildVerdict(
235
- guardVerdict.status,
236
- guardVerdict.reason,
237
- guardVerdict.ruleId,
238
- void 0,
239
- world,
240
- level,
241
- invariantChecks,
242
- guardsMatched,
243
- rulesMatched,
244
- includeTrace ? buildTrace(
245
- invariantChecks,
246
- safetyChecks,
247
- planCheckResult,
248
- roleChecks,
249
- guardChecks,
250
- kernelRuleChecks,
251
- levelChecks,
252
- decidingLayer,
253
- decidingId,
254
- startTime
255
- ) : void 0
256
- );
257
- }
258
- }
259
- const kernelVerdict = checkKernelRules(eventText, world, kernelRuleChecks, rulesMatched);
260
- if (kernelVerdict) {
261
- decidingLayer = "kernel-rule";
262
- decidingId = kernelVerdict.ruleId;
263
- return buildVerdict(
264
- kernelVerdict.status,
265
- kernelVerdict.reason,
266
- kernelVerdict.ruleId,
267
- void 0,
268
- world,
269
- level,
270
- invariantChecks,
271
- guardsMatched,
272
- rulesMatched,
273
- includeTrace ? buildTrace(
274
- invariantChecks,
275
- safetyChecks,
276
- planCheckResult,
277
- roleChecks,
278
- guardChecks,
279
- kernelRuleChecks,
280
- levelChecks,
281
- decidingLayer,
282
- decidingId,
283
- startTime
284
- ) : void 0
285
- );
286
- }
287
- const levelVerdict = checkLevelConstraints(event, level, levelChecks);
288
- if (levelVerdict) {
289
- decidingLayer = "level-constraint";
290
- decidingId = levelVerdict.ruleId;
291
- return buildVerdict(
292
- levelVerdict.status,
293
- levelVerdict.reason,
294
- levelVerdict.ruleId,
295
- void 0,
296
- world,
297
- level,
298
- invariantChecks,
299
- guardsMatched,
300
- rulesMatched,
301
- includeTrace ? buildTrace(
302
- invariantChecks,
303
- safetyChecks,
304
- planCheckResult,
305
- roleChecks,
306
- guardChecks,
307
- kernelRuleChecks,
308
- levelChecks,
309
- decidingLayer,
310
- decidingId,
311
- startTime
312
- ) : void 0
313
- );
314
- }
315
- const warning = guardVerdict?.warning;
316
- return buildVerdict(
317
- "ALLOW",
318
- void 0,
319
- void 0,
320
- warning,
321
- world,
322
- level,
323
- invariantChecks,
324
- guardsMatched,
325
- rulesMatched,
326
- includeTrace ? buildTrace(
327
- invariantChecks,
328
- safetyChecks,
329
- planCheckResult,
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, planCheck, roleChecks, guardChecks, kernelRuleChecks, levelChecks, decidingLayer, decidingId, startTime) {
668
- const trace = {
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
- "plan-enforcement",
687
- "role-rules",
688
- "declarative-guards",
689
- "kernel-rules",
690
- "level-constraints",
691
- "default-allow"
692
- ]
693
- },
694
- durationMs: performance.now() - startTime
695
- };
696
- if (planCheck) {
697
- trace.planCheck = planCheck;
698
- }
699
- return trace;
700
- }
701
- function buildVerdict(status, reason, ruleId, warning, world, level, invariantChecks, guardsMatched, rulesMatched, trace) {
702
- const evidence = {
703
- worldId: world.world.world_id,
704
- worldName: world.world.name,
705
- worldVersion: world.world.version,
706
- evaluatedAt: Date.now(),
707
- invariantsSatisfied: invariantChecks.filter((c) => c.hasGuardCoverage).length,
708
- invariantsTotal: invariantChecks.length,
709
- guardsMatched,
710
- rulesMatched,
711
- enforcementLevel: level
712
- };
713
- const verdict = {
714
- status,
715
- evidence
716
- };
717
- if (reason) verdict.reason = reason;
718
- if (ruleId) verdict.ruleId = ruleId;
719
- if (warning) verdict.warning = warning;
720
- if (trace) verdict.trace = trace;
721
- return verdict;
722
- }
723
-
724
- export {
725
- evaluateGuard,
726
- eventToAllowlistKey
727
- };