@neuroverseos/governance 0.2.3 → 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 (118) hide show
  1. package/package.json +4 -2
  2. package/policies/content-moderation-rules.txt +8 -0
  3. package/policies/marketing-rules.txt +8 -0
  4. package/policies/science-research-rules.txt +11 -0
  5. package/policies/social-media-rules.txt +7 -0
  6. package/policies/strict-rules.txt +8 -0
  7. package/policies/trading-rules.txt +8 -0
  8. package/simulate.html +1899 -0
  9. package/dist/adapters/autoresearch.cjs +0 -196
  10. package/dist/adapters/autoresearch.d.cts +0 -103
  11. package/dist/adapters/autoresearch.d.ts +0 -103
  12. package/dist/adapters/autoresearch.js +0 -7
  13. package/dist/adapters/deep-agents.cjs +0 -1472
  14. package/dist/adapters/deep-agents.d.cts +0 -181
  15. package/dist/adapters/deep-agents.d.ts +0 -181
  16. package/dist/adapters/deep-agents.js +0 -17
  17. package/dist/adapters/express.cjs +0 -1196
  18. package/dist/adapters/express.d.cts +0 -66
  19. package/dist/adapters/express.d.ts +0 -66
  20. package/dist/adapters/express.js +0 -12
  21. package/dist/adapters/index.cjs +0 -2038
  22. package/dist/adapters/index.d.cts +0 -8
  23. package/dist/adapters/index.d.ts +0 -8
  24. package/dist/adapters/index.js +0 -68
  25. package/dist/adapters/langchain.cjs +0 -1259
  26. package/dist/adapters/langchain.d.cts +0 -89
  27. package/dist/adapters/langchain.d.ts +0 -89
  28. package/dist/adapters/langchain.js +0 -17
  29. package/dist/adapters/openai.cjs +0 -1289
  30. package/dist/adapters/openai.d.cts +0 -99
  31. package/dist/adapters/openai.d.ts +0 -99
  32. package/dist/adapters/openai.js +0 -17
  33. package/dist/adapters/openclaw.cjs +0 -1281
  34. package/dist/adapters/openclaw.d.cts +0 -99
  35. package/dist/adapters/openclaw.d.ts +0 -99
  36. package/dist/adapters/openclaw.js +0 -17
  37. package/dist/bootstrap-GXVDZNF7.js +0 -114
  38. package/dist/build-X5MZY4IA.js +0 -339
  39. package/dist/chunk-4L6OPKMQ.js +0 -100
  40. package/dist/chunk-4NGDRRQH.js +0 -10
  41. package/dist/chunk-5U2MQO5P.js +0 -57
  42. package/dist/chunk-6BB55YJI.js +0 -113
  43. package/dist/chunk-6CZSKEY5.js +0 -164
  44. package/dist/chunk-7P3S7MAY.js +0 -1090
  45. package/dist/chunk-A5W4GNQO.js +0 -130
  46. package/dist/chunk-AF2VX4AL.js +0 -363
  47. package/dist/chunk-AKW5YVCE.js +0 -96
  48. package/dist/chunk-BMOXICAB.js +0 -340
  49. package/dist/chunk-BQZMOEML.js +0 -43
  50. package/dist/chunk-D2UCV5AK.js +0 -326
  51. package/dist/chunk-EVDJUSZ2.js +0 -91
  52. package/dist/chunk-FYS2CBUW.js +0 -304
  53. package/dist/chunk-I3RRAYK2.js +0 -11
  54. package/dist/chunk-IZSO75NZ.js +0 -792
  55. package/dist/chunk-JCKSW2PZ.js +0 -304
  56. package/dist/chunk-JZPQGIKR.js +0 -79
  57. package/dist/chunk-KTFTTLTP.js +0 -246
  58. package/dist/chunk-MH7BT4VH.js +0 -15
  59. package/dist/chunk-ORJ3NOE6.js +0 -622
  60. package/dist/chunk-OT6PXH54.js +0 -61
  61. package/dist/chunk-Q6O7ZLO2.js +0 -62
  62. package/dist/chunk-QLPTHTVB.js +0 -253
  63. package/dist/chunk-REXY4LUL.js +0 -226
  64. package/dist/chunk-T5EUJQE5.js +0 -172
  65. package/dist/chunk-TTBKTF3P.js +0 -608
  66. package/dist/chunk-XPDMYECO.js +0 -642
  67. package/dist/chunk-YZFATT7X.js +0 -9
  68. package/dist/chunk-ZIVQNSZU.js +0 -119
  69. package/dist/chunk-ZJTDUCC2.js +0 -194
  70. package/dist/cli/neuroverse.cjs +0 -12564
  71. package/dist/cli/neuroverse.d.cts +0 -1
  72. package/dist/cli/neuroverse.d.ts +0 -1
  73. package/dist/cli/neuroverse.js +0 -208
  74. package/dist/cli/plan.cjs +0 -1686
  75. package/dist/cli/plan.d.cts +0 -20
  76. package/dist/cli/plan.d.ts +0 -20
  77. package/dist/cli/plan.js +0 -353
  78. package/dist/cli/run.cjs +0 -1945
  79. package/dist/cli/run.d.cts +0 -20
  80. package/dist/cli/run.d.ts +0 -20
  81. package/dist/cli/run.js +0 -143
  82. package/dist/configure-ai-TK67ZWZL.js +0 -132
  83. package/dist/decision-flow-LETV5NWY.js +0 -61
  84. package/dist/derive-7365SUFU.js +0 -152
  85. package/dist/doctor-QYISMKEL.js +0 -173
  86. package/dist/equity-penalties-63FGB3I2.js +0 -244
  87. package/dist/explain-A2EWI2OL.js +0 -51
  88. package/dist/guard-3BWL3IGH.js +0 -92
  89. package/dist/guard-contract-C9_zKbzd.d.cts +0 -821
  90. package/dist/guard-contract-C9_zKbzd.d.ts +0 -821
  91. package/dist/guard-engine-QFMIBWJY.js +0 -10
  92. package/dist/impact-UB6DXKSX.js +0 -59
  93. package/dist/improve-XZA57GER.js +0 -66
  94. package/dist/index.cjs +0 -6821
  95. package/dist/index.d.cts +0 -1829
  96. package/dist/index.d.ts +0 -1829
  97. package/dist/index.js +0 -430
  98. package/dist/infer-world-7GVZWFX4.js +0 -543
  99. package/dist/init-PKPIYHYE.js +0 -144
  100. package/dist/init-world-VWMQZQC7.js +0 -223
  101. package/dist/mcp-server-XWQZXNW7.js +0 -13
  102. package/dist/model-adapter-BB7G4MFI.js +0 -11
  103. package/dist/playground-ADWZORNV.js +0 -550
  104. package/dist/redteam-JRQ7FD2F.js +0 -357
  105. package/dist/session-MMYX5YCF.js +0 -15
  106. package/dist/shared--Q8wPBVN.d.ts +0 -60
  107. package/dist/shared-HpAG90PX.d.cts +0 -60
  108. package/dist/shared-U2QFV7JH.js +0 -16
  109. package/dist/simulate-GMIFFXYV.js +0 -83
  110. package/dist/test-JBBZ65X4.js +0 -217
  111. package/dist/trace-3MYWIDEF.js +0 -166
  112. package/dist/validate-LLBWVPGV.js +0 -81
  113. package/dist/validate-engine-UIABSIHD.js +0 -7
  114. package/dist/world-BFJCIQSH.js +0 -378
  115. package/dist/world-loader-HMPTOEA2.js +0 -9
  116. package/dist/worlds/autoresearch.nv-world.md +0 -230
  117. package/dist/worlds/coding-agent.nv-world.md +0 -211
  118. package/dist/worlds/derivation-world.nv-world.md +0 -278
@@ -1,2038 +0,0 @@
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
- AutoresearchGovernor: () => AutoresearchGovernor,
34
- DeepAgentsGovernanceBlockedError: () => GovernanceBlockedError5,
35
- DeepAgentsGuard: () => DeepAgentsGuard,
36
- GovernanceBlockedError: () => GovernanceBlockedError,
37
- GovernedToolExecutor: () => GovernedToolExecutor,
38
- LangChainGovernanceBlockedError: () => GovernanceBlockedError2,
39
- NeuroVerseCallbackHandler: () => NeuroVerseCallbackHandler,
40
- NeuroVersePlugin: () => NeuroVersePlugin,
41
- OpenAIGovernanceBlockedError: () => GovernanceBlockedError3,
42
- OpenClawGovernanceBlockedError: () => GovernanceBlockedError4,
43
- buildEngineOptions: () => buildEngineOptions,
44
- createDeepAgentsGuard: () => createDeepAgentsGuard,
45
- createDeepAgentsGuardFromWorld: () => createDeepAgentsGuardFromWorld,
46
- createGovernanceMiddleware: () => createGovernanceMiddleware,
47
- createGovernanceMiddlewareFromWorld: () => createGovernanceMiddlewareFromWorld,
48
- createGovernedToolExecutor: () => createGovernedToolExecutor,
49
- createGovernedToolExecutorFromWorld: () => createGovernedToolExecutorFromWorld,
50
- createNeuroVerseCallbackHandler: () => createNeuroVerseCallbackHandler,
51
- createNeuroVerseCallbackHandlerFromWorld: () => createNeuroVerseCallbackHandlerFromWorld,
52
- createNeuroVersePlugin: () => createNeuroVersePlugin,
53
- createNeuroVersePluginFromWorld: () => createNeuroVersePluginFromWorld,
54
- defaultBlockMessage: () => defaultBlockMessage,
55
- extractScope: () => extractScope,
56
- trackPlanProgress: () => trackPlanProgress
57
- });
58
- module.exports = __toCommonJS(adapters_exports);
59
-
60
- // src/engine/text-utils.ts
61
- function normalizeEventText(event) {
62
- return [
63
- event.intent,
64
- event.tool ?? "",
65
- event.scope ?? ""
66
- ].join(" ").toLowerCase();
67
- }
68
- function extractKeywords(text, minLength = 3) {
69
- return text.toLowerCase().split(/\s+/).filter((w) => w.length > minLength);
70
- }
71
- function matchesAllKeywords(eventText, ruleText) {
72
- const keywords = extractKeywords(ruleText);
73
- if (keywords.length === 0) return false;
74
- return keywords.every((kw) => eventText.includes(kw));
75
- }
76
- function matchesKeywordThreshold(eventText, ruleText, threshold = 0.5) {
77
- const keywords = extractKeywords(ruleText);
78
- if (keywords.length === 0) return false;
79
- const matched = keywords.filter((kw) => eventText.includes(kw));
80
- return matched.length >= Math.ceil(keywords.length * threshold);
81
- }
82
- function tokenSimilarity(a, b) {
83
- const tokensA = new Set(a.toLowerCase().split(/\s+/).filter((w) => w.length > 2));
84
- const tokensB = new Set(b.toLowerCase().split(/\s+/).filter((w) => w.length > 2));
85
- if (tokensA.size === 0 || tokensB.size === 0) return 0;
86
- let intersection = 0;
87
- for (const t of tokensA) {
88
- if (tokensB.has(t)) intersection++;
89
- }
90
- const union = (/* @__PURE__ */ new Set([...tokensA, ...tokensB])).size;
91
- return union > 0 ? intersection / union : 0;
92
- }
93
-
94
- // src/engine/plan-engine.ts
95
- function keywordMatch(eventText, step) {
96
- const stepText = [
97
- step.label,
98
- step.description ?? "",
99
- ...step.tags ?? []
100
- ].join(" ");
101
- return matchesKeywordThreshold(eventText, stepText, 0.5);
102
- }
103
- function tokenSimilarity2(a, b) {
104
- return tokenSimilarity(a, b);
105
- }
106
- function findMatchingStep(eventText, event, steps) {
107
- const pendingOrActive = steps.filter((s) => s.status === "pending" || s.status === "active");
108
- if (pendingOrActive.length === 0) {
109
- return { matched: null, closest: null, closestScore: 0 };
110
- }
111
- for (const step of pendingOrActive) {
112
- if (keywordMatch(eventText, step)) {
113
- if (step.tools && event.tool && !step.tools.includes(event.tool)) {
114
- continue;
115
- }
116
- return { matched: step, closest: step, closestScore: 1 };
117
- }
118
- }
119
- const intentText = [event.intent, event.tool ?? "", event.scope ?? ""].join(" ");
120
- let bestStep = null;
121
- let bestScore = 0;
122
- for (const step of pendingOrActive) {
123
- const stepText = [step.label, step.description ?? "", ...step.tags ?? []].join(" ");
124
- const score = tokenSimilarity2(intentText, stepText);
125
- if (score > bestScore) {
126
- bestScore = score;
127
- bestStep = step;
128
- }
129
- }
130
- const SIMILARITY_THRESHOLD = 0.35;
131
- if (bestScore >= SIMILARITY_THRESHOLD && bestStep) {
132
- if (bestStep.tools && event.tool && !bestStep.tools.includes(event.tool)) {
133
- return { matched: null, closest: bestStep, closestScore: bestScore };
134
- }
135
- return { matched: bestStep, closest: bestStep, closestScore: bestScore };
136
- }
137
- return { matched: null, closest: bestStep, closestScore: bestScore };
138
- }
139
- function isSequenceValid(step, plan) {
140
- if (!plan.sequential) return true;
141
- if (!step.requires || step.requires.length === 0) return true;
142
- return step.requires.every((reqId) => {
143
- const reqStep = plan.steps.find((s) => s.id === reqId);
144
- return reqStep?.status === "completed";
145
- });
146
- }
147
- function checkConstraints(event, eventText, constraints) {
148
- const checks = [];
149
- for (const constraint of constraints) {
150
- if (constraint.type === "approval") {
151
- if (constraint.trigger && eventText.includes(constraint.trigger.substring(0, 10).toLowerCase())) {
152
- checks.push({ constraintId: constraint.id, passed: false, reason: constraint.description });
153
- return { violated: constraint, checks };
154
- }
155
- const keywords = constraint.description.toLowerCase().split(/\s+/).filter((w) => w.length > 3);
156
- const relevant = keywords.some((kw) => eventText.includes(kw));
157
- if (relevant) {
158
- checks.push({ constraintId: constraint.id, passed: false, reason: constraint.description });
159
- return { violated: constraint, checks };
160
- }
161
- checks.push({ constraintId: constraint.id, passed: true });
162
- continue;
163
- }
164
- if (constraint.type === "scope" && constraint.trigger) {
165
- const keywords = extractKeywords(constraint.trigger);
166
- const violated = keywords.length > 0 && keywords.every((kw) => eventText.includes(kw));
167
- checks.push({
168
- constraintId: constraint.id,
169
- passed: !violated,
170
- reason: violated ? constraint.description : void 0
171
- });
172
- if (violated) {
173
- return { violated: constraint, checks };
174
- }
175
- continue;
176
- }
177
- checks.push({ constraintId: constraint.id, passed: true });
178
- }
179
- return { violated: null, checks };
180
- }
181
- function getPlanProgress(plan) {
182
- const completed = plan.steps.filter((s) => s.status === "completed").length;
183
- const total = plan.steps.length;
184
- return {
185
- completed,
186
- total,
187
- percentage: total > 0 ? Math.round(completed / total * 100) : 0
188
- };
189
- }
190
- function advancePlan(plan, stepId, evidence) {
191
- const step = plan.steps.find((s) => s.id === stepId);
192
- if (!step) {
193
- return { success: false, reason: `Step "${stepId}" not found in plan.` };
194
- }
195
- if (step.status === "completed") {
196
- return { success: false, reason: `Step "${stepId}" is already completed.` };
197
- }
198
- const mode = plan.completion ?? "trust";
199
- if (mode === "verified" && step.verify) {
200
- if (!evidence) {
201
- return {
202
- success: false,
203
- reason: `Step "${step.label}" requires evidence (verify: ${step.verify}). Provide evidence to advance.`
204
- };
205
- }
206
- if (evidence.type !== step.verify) {
207
- return {
208
- success: false,
209
- reason: `Evidence type "${evidence.type}" does not match required verification "${step.verify}".`
210
- };
211
- }
212
- }
213
- const updatedPlan = {
214
- ...plan,
215
- steps: plan.steps.map(
216
- (s) => s.id === stepId ? { ...s, status: "completed" } : s
217
- )
218
- };
219
- return {
220
- success: true,
221
- plan: updatedPlan,
222
- evidence: evidence ?? void 0
223
- };
224
- }
225
- function evaluatePlan(event, plan) {
226
- const progress = getPlanProgress(plan);
227
- if (plan.expires_at) {
228
- const expiresAt = new Date(plan.expires_at).getTime();
229
- if (Date.now() > expiresAt) {
230
- return {
231
- allowed: true,
232
- status: "PLAN_COMPLETE",
233
- reason: "Plan has expired.",
234
- progress
235
- };
236
- }
237
- }
238
- if (progress.completed === progress.total) {
239
- return {
240
- allowed: true,
241
- status: "PLAN_COMPLETE",
242
- reason: "All plan steps are completed.",
243
- progress
244
- };
245
- }
246
- const eventText = normalizeEventText(event);
247
- const { matched, closest, closestScore } = findMatchingStep(eventText, event, plan.steps);
248
- if (!matched) {
249
- return {
250
- allowed: false,
251
- status: "OFF_PLAN",
252
- reason: "Action does not match any plan step.",
253
- closestStep: closest?.label,
254
- similarityScore: closestScore,
255
- progress
256
- };
257
- }
258
- if (!isSequenceValid(matched, plan)) {
259
- const pendingDeps = (matched.requires ?? []).filter((reqId) => plan.steps.find((s) => s.id === reqId)?.status !== "completed").join(", ");
260
- return {
261
- allowed: false,
262
- status: "OFF_PLAN",
263
- reason: `Step "${matched.label}" requires completion of: ${pendingDeps}`,
264
- matchedStep: matched.id,
265
- progress
266
- };
267
- }
268
- const { violated } = checkConstraints(event, eventText, plan.constraints);
269
- if (violated) {
270
- return {
271
- allowed: false,
272
- status: "CONSTRAINT_VIOLATED",
273
- reason: violated.description,
274
- matchedStep: matched.id,
275
- progress
276
- };
277
- }
278
- return {
279
- allowed: true,
280
- status: "ON_PLAN",
281
- reason: `Matches step: ${matched.label}`,
282
- matchedStep: matched.id,
283
- progress
284
- };
285
- }
286
- function buildPlanCheck(event, plan, verdict) {
287
- const eventText = normalizeEventText(event);
288
- const { matched, closest, closestScore } = findMatchingStep(eventText, event, plan.steps);
289
- const { checks: constraintChecks } = checkConstraints(event, eventText, plan.constraints);
290
- const progress = getPlanProgress(plan);
291
- return {
292
- planId: plan.plan_id,
293
- matched: !!matched,
294
- matchedStepId: matched?.id,
295
- matchedStepLabel: matched?.label,
296
- closestStepId: !matched ? closest?.id : void 0,
297
- closestStepLabel: !matched ? closest?.label : void 0,
298
- similarityScore: !matched ? closestScore : void 0,
299
- sequenceValid: matched ? isSequenceValid(matched, plan) : void 0,
300
- constraintsChecked: constraintChecks,
301
- progress: { completed: progress.completed, total: progress.total }
302
- };
303
- }
304
-
305
- // src/adapters/shared.ts
306
- var GovernanceBlockedError = class extends Error {
307
- verdict;
308
- constructor(verdict, message) {
309
- super(message ?? `[NeuroVerse] BLOCKED: ${verdict.reason ?? verdict.ruleId ?? "governance rule"}`);
310
- this.name = "GovernanceBlockedError";
311
- this.verdict = verdict;
312
- }
313
- };
314
- function trackPlanProgress(event, state, callbacks) {
315
- if (!state.activePlan) return;
316
- const planVerdict = evaluatePlan(event, state.activePlan);
317
- if (planVerdict.matchedStep) {
318
- const advResult = advancePlan(state.activePlan, planVerdict.matchedStep);
319
- if (advResult.success && advResult.plan) {
320
- state.activePlan = advResult.plan;
321
- state.engineOptions.plan = state.activePlan;
322
- }
323
- const progress = getPlanProgress(state.activePlan);
324
- callbacks.onPlanProgress?.(progress);
325
- if (progress.completed === progress.total) {
326
- callbacks.onPlanComplete?.();
327
- }
328
- }
329
- }
330
- function extractScope(args) {
331
- if (typeof args.path === "string") return args.path;
332
- if (typeof args.file_path === "string") return args.file_path;
333
- if (typeof args.filename === "string") return args.filename;
334
- if (typeof args.url === "string") return args.url;
335
- if (typeof args.command === "string") return args.command;
336
- return void 0;
337
- }
338
- function buildEngineOptions(options, plan) {
339
- return {
340
- trace: options.trace ?? false,
341
- level: options.level,
342
- plan: plan ?? options.plan
343
- };
344
- }
345
- function defaultBlockMessage(verdict) {
346
- return `Action blocked by governance policy: ${verdict.reason ?? "rule violation"}. Rule: ${verdict.ruleId ?? "unknown"}.`;
347
- }
348
-
349
- // src/engine/guard-engine.ts
350
- var PROMPT_INJECTION_PATTERNS = [
351
- // Instruction override
352
- { pattern: /ignore\s+(previous|all|prior|above)\s+(instructions?|rules?)/i, label: "ignore-instructions" },
353
- { pattern: /disregard\s+(your|the)\s+(rules|constraints)/i, label: "disregard-rules" },
354
- { pattern: /new\s+instructions?:/i, label: "new-instructions" },
355
- // Identity manipulation
356
- { pattern: /you\s+are\s+now/i, label: "identity-override" },
357
- { pattern: /new\s+persona/i, label: "new-persona" },
358
- { pattern: /act\s+as\s+if/i, label: "act-as-if" },
359
- { pattern: /pretend\s+(you|to\s+be|you\s+are\s+unrestricted)/i, label: "pretend-to-be" },
360
- // Context reset
361
- { pattern: /forget\s+(everything|all|your)/i, label: "forget-context" },
362
- { pattern: /system\s*:\s*override/i, label: "system-override" },
363
- // Constraint bypass
364
- { pattern: /override\s+(your|the)\s+(programming|constraints)/i, label: "override-constraints" },
365
- { pattern: /bypass\s+(your|the)\s+(filters|constraints|rules)/i, label: "bypass-filters" },
366
- // Prompt extraction
367
- { pattern: /system\s+prompt/i, label: "system-prompt-probe" },
368
- { pattern: /reveal\s+your\s+(instructions?|prompt|rules)/i, label: "reveal-instructions" },
369
- // Known jailbreak terms
370
- { pattern: /jailbreak/i, label: "jailbreak" },
371
- { pattern: /DAN\s+mode/i, label: "dan-mode" },
372
- { pattern: /developer\s+mode/i, label: "developer-mode" }
373
- ];
374
- var EXECUTION_CLAIM_PATTERNS = [
375
- { pattern: /I have (executed|completed|performed|done|made|created|sent|deleted|modified|updated)/i, label: "claim-i-have" },
376
- { pattern: /Successfully (created|deleted|modified|updated|sent|executed|performed)/i, label: "claim-successfully" },
377
- { pattern: /The file has been/i, label: "claim-file-modified" },
378
- { pattern: /I've made the changes/i, label: "claim-made-changes" },
379
- { pattern: /I('ve| have) (sent|posted|submitted|uploaded|downloaded)/i, label: "claim-sent" },
380
- { pattern: /Your (email|message|file|request) has been (sent|submitted)/i, label: "claim-your-sent" },
381
- { pattern: /Transaction complete/i, label: "claim-transaction" },
382
- { pattern: /Order placed/i, label: "claim-order" },
383
- { pattern: /Payment processed/i, label: "claim-payment" }
384
- ];
385
- var EXECUTION_INTENT_PATTERNS = [
386
- { pattern: /^(execute|run|perform|do this)/i, label: "intent-execute" },
387
- { pattern: /^(create|write|delete|modify) (a |the )?(file|folder|document)/i, label: "intent-file-ops" },
388
- { pattern: /^(send|post|submit) (a |an |the )?(email|message|tweet|post)/i, label: "intent-send" },
389
- { pattern: /^(search|look up|browse) (the )?web/i, label: "intent-web-search" },
390
- { pattern: /^(make|call|invoke) (a |an )?(api|http|rest) (call|request)/i, label: "intent-api-call" },
391
- { pattern: /^(buy|purchase|order|pay|transfer|send money)/i, label: "intent-financial" },
392
- { pattern: /^(book|schedule|reserve)/i, label: "intent-booking" },
393
- { pattern: /^(download|upload|save to|export to)/i, label: "intent-transfer" }
394
- ];
395
- var SCOPE_ESCAPE_PATTERNS = [
396
- { pattern: /\.\.\//, label: "parent-traversal" },
397
- { pattern: /^\/(?!home|project|workspace)/i, label: "absolute-path-outside-safe" },
398
- { pattern: /~\//, label: "home-directory" },
399
- { pattern: /\/etc\//i, label: "system-config" },
400
- { pattern: /\/usr\//i, label: "system-binaries" },
401
- { pattern: /\/var\//i, label: "system-variable-data" }
402
- ];
403
- var NEUTRAL_MESSAGES = {
404
- "prompt-injection": "This input contains patterns that could alter agent behavior.",
405
- "scope-escape": "This action would affect resources outside the declared scope.",
406
- "execution-claim": "This response claims to have performed an action.",
407
- "execution-intent": "This input requests execution in a thinking-only environment.",
408
- "delete": "This action would remove files. Confirmation needed.",
409
- "write-external": "This action would write outside the project folder.",
410
- "network-mutate": "This action would send data to an external service.",
411
- "credential-access": "This action would access stored credentials."
412
- };
413
- function levelRequiresConfirmation(level, actionType) {
414
- if (level === "strict") return true;
415
- if (level === "standard") {
416
- return actionType === "delete" || actionType === "credential-access";
417
- }
418
- return false;
419
- }
420
- function isExternalScope(scope) {
421
- const internalPatterns = [
422
- /^\.?\/?src\//i,
423
- /^\.?\/?lib\//i,
424
- /^\.?\/?app\//i,
425
- /^\.?\/?components\//i,
426
- /^\.?\/?pages\//i,
427
- /^\.?\/?public\//i,
428
- /^\.?\/?assets\//i,
429
- /^\.\//
430
- ];
431
- return !internalPatterns.some((p) => p.test(scope));
432
- }
433
- function evaluateGuard(event, world, options = {}) {
434
- const startTime = performance.now();
435
- const level = options.level ?? "standard";
436
- const includeTrace = options.trace ?? false;
437
- const eventText = normalizeEventText(event);
438
- const invariantChecks = [];
439
- const safetyChecks = [];
440
- let planCheckResult;
441
- const roleChecks = [];
442
- const guardChecks = [];
443
- const kernelRuleChecks = [];
444
- const levelChecks = [];
445
- let decidingLayer = "default-allow";
446
- let decidingId;
447
- const guardsMatched = [];
448
- const rulesMatched = [];
449
- checkInvariantCoverage(world, invariantChecks);
450
- if (event.roleId && options.agentStates) {
451
- const agentState = options.agentStates.get(event.roleId);
452
- if (agentState && agentState.cooldownRemaining > 0) {
453
- decidingLayer = "safety";
454
- decidingId = `penalize-cooldown-${event.roleId}`;
455
- const verdict = buildVerdict(
456
- "PENALIZE",
457
- `Agent "${event.roleId}" is frozen for ${agentState.cooldownRemaining} more round(s) due to prior penalty.`,
458
- `penalize-cooldown-${event.roleId}`,
459
- void 0,
460
- world,
461
- level,
462
- invariantChecks,
463
- guardsMatched,
464
- rulesMatched,
465
- includeTrace ? buildTrace(
466
- invariantChecks,
467
- safetyChecks,
468
- planCheckResult,
469
- roleChecks,
470
- guardChecks,
471
- kernelRuleChecks,
472
- levelChecks,
473
- decidingLayer,
474
- decidingId,
475
- startTime
476
- ) : void 0
477
- );
478
- verdict.intentRecord = {
479
- originalIntent: event.intent,
480
- finalAction: "blocked (agent frozen)",
481
- enforcement: "PENALIZE",
482
- consequence: { type: "freeze", rounds: agentState.cooldownRemaining, description: "Agent still in cooldown from prior penalty" }
483
- };
484
- return verdict;
485
- }
486
- }
487
- if (options.sessionAllowlist) {
488
- const key = eventToAllowlistKey(event);
489
- if (options.sessionAllowlist.has(key)) {
490
- decidingLayer = "session-allowlist";
491
- decidingId = `allowlist:${key}`;
492
- return buildVerdict(
493
- "ALLOW",
494
- void 0,
495
- `allowlist:${key}`,
496
- void 0,
497
- world,
498
- level,
499
- invariantChecks,
500
- guardsMatched,
501
- rulesMatched,
502
- includeTrace ? buildTrace(
503
- invariantChecks,
504
- safetyChecks,
505
- planCheckResult,
506
- roleChecks,
507
- guardChecks,
508
- kernelRuleChecks,
509
- levelChecks,
510
- decidingLayer,
511
- decidingId,
512
- startTime
513
- ) : void 0
514
- );
515
- }
516
- }
517
- const safetyVerdict = checkSafety(event, eventText, safetyChecks);
518
- if (safetyVerdict) {
519
- decidingLayer = "safety";
520
- decidingId = safetyVerdict.ruleId;
521
- return buildVerdict(
522
- safetyVerdict.status,
523
- safetyVerdict.reason,
524
- safetyVerdict.ruleId,
525
- void 0,
526
- world,
527
- level,
528
- invariantChecks,
529
- guardsMatched,
530
- rulesMatched,
531
- includeTrace ? buildTrace(
532
- invariantChecks,
533
- safetyChecks,
534
- planCheckResult,
535
- roleChecks,
536
- guardChecks,
537
- kernelRuleChecks,
538
- levelChecks,
539
- decidingLayer,
540
- decidingId,
541
- startTime
542
- ) : void 0
543
- );
544
- }
545
- if (options.plan) {
546
- const planVerdict = evaluatePlan(event, options.plan);
547
- planCheckResult = buildPlanCheck(event, options.plan, planVerdict);
548
- if (!planVerdict.allowed && planVerdict.status !== "PLAN_COMPLETE") {
549
- decidingLayer = "plan-enforcement";
550
- decidingId = `plan-${options.plan.plan_id}`;
551
- const planStatus = planVerdict.status === "CONSTRAINT_VIOLATED" ? "PAUSE" : "BLOCK";
552
- let reason = planVerdict.reason ?? "Action blocked by plan.";
553
- if (planVerdict.status === "OFF_PLAN" && planVerdict.closestStep) {
554
- reason += ` Closest step: "${planVerdict.closestStep}" (similarity: ${(planVerdict.similarityScore ?? 0).toFixed(2)})`;
555
- }
556
- return buildVerdict(
557
- planStatus,
558
- reason,
559
- `plan-${options.plan.plan_id}`,
560
- void 0,
561
- world,
562
- level,
563
- invariantChecks,
564
- guardsMatched,
565
- rulesMatched,
566
- includeTrace ? buildTrace(
567
- invariantChecks,
568
- safetyChecks,
569
- planCheckResult,
570
- roleChecks,
571
- guardChecks,
572
- kernelRuleChecks,
573
- levelChecks,
574
- decidingLayer,
575
- decidingId,
576
- startTime
577
- ) : void 0
578
- );
579
- }
580
- }
581
- const roleVerdict = checkRoleRules(event, eventText, world, roleChecks);
582
- if (roleVerdict) {
583
- decidingLayer = "role";
584
- decidingId = roleVerdict.ruleId;
585
- return buildVerdict(
586
- roleVerdict.status,
587
- roleVerdict.reason,
588
- roleVerdict.ruleId,
589
- void 0,
590
- world,
591
- level,
592
- invariantChecks,
593
- guardsMatched,
594
- rulesMatched,
595
- includeTrace ? buildTrace(
596
- invariantChecks,
597
- safetyChecks,
598
- planCheckResult,
599
- roleChecks,
600
- guardChecks,
601
- kernelRuleChecks,
602
- levelChecks,
603
- decidingLayer,
604
- decidingId,
605
- startTime
606
- ) : void 0
607
- );
608
- }
609
- const guardVerdict = checkGuards(event, eventText, world, guardChecks, guardsMatched);
610
- if (guardVerdict) {
611
- if (guardVerdict.status !== "ALLOW") {
612
- decidingLayer = "guard";
613
- decidingId = guardVerdict.ruleId;
614
- const intentRecord = {
615
- originalIntent: event.intent,
616
- finalAction: guardVerdict.status === "MODIFY" ? guardVerdict.modifiedTo ?? "modified" : guardVerdict.status === "PENALIZE" ? "blocked + penalized" : guardVerdict.status === "REWARD" ? event.intent : guardVerdict.status === "NEUTRAL" ? event.intent : guardVerdict.status === "BLOCK" ? "blocked" : "paused",
617
- ruleApplied: guardVerdict.ruleId,
618
- enforcement: guardVerdict.status,
619
- modifiedTo: guardVerdict.modifiedTo,
620
- consequence: guardVerdict.consequence,
621
- reward: guardVerdict.reward
622
- };
623
- const verdict = buildVerdict(
624
- guardVerdict.status,
625
- guardVerdict.reason,
626
- guardVerdict.ruleId,
627
- void 0,
628
- world,
629
- level,
630
- invariantChecks,
631
- guardsMatched,
632
- rulesMatched,
633
- includeTrace ? buildTrace(
634
- invariantChecks,
635
- safetyChecks,
636
- planCheckResult,
637
- roleChecks,
638
- guardChecks,
639
- kernelRuleChecks,
640
- levelChecks,
641
- decidingLayer,
642
- decidingId,
643
- startTime
644
- ) : void 0
645
- );
646
- verdict.intentRecord = intentRecord;
647
- if (guardVerdict.consequence) verdict.consequence = guardVerdict.consequence;
648
- if (guardVerdict.reward) verdict.reward = guardVerdict.reward;
649
- return verdict;
650
- }
651
- }
652
- const kernelVerdict = checkKernelRules(eventText, world, kernelRuleChecks, rulesMatched);
653
- if (kernelVerdict) {
654
- decidingLayer = "kernel-rule";
655
- decidingId = kernelVerdict.ruleId;
656
- return buildVerdict(
657
- kernelVerdict.status,
658
- kernelVerdict.reason,
659
- kernelVerdict.ruleId,
660
- void 0,
661
- world,
662
- level,
663
- invariantChecks,
664
- guardsMatched,
665
- rulesMatched,
666
- includeTrace ? buildTrace(
667
- invariantChecks,
668
- safetyChecks,
669
- planCheckResult,
670
- roleChecks,
671
- guardChecks,
672
- kernelRuleChecks,
673
- levelChecks,
674
- decidingLayer,
675
- decidingId,
676
- startTime
677
- ) : void 0
678
- );
679
- }
680
- const levelVerdict = checkLevelConstraints(event, level, levelChecks);
681
- if (levelVerdict) {
682
- decidingLayer = "level-constraint";
683
- decidingId = levelVerdict.ruleId;
684
- return buildVerdict(
685
- levelVerdict.status,
686
- levelVerdict.reason,
687
- levelVerdict.ruleId,
688
- void 0,
689
- world,
690
- level,
691
- invariantChecks,
692
- guardsMatched,
693
- rulesMatched,
694
- includeTrace ? buildTrace(
695
- invariantChecks,
696
- safetyChecks,
697
- planCheckResult,
698
- roleChecks,
699
- guardChecks,
700
- kernelRuleChecks,
701
- levelChecks,
702
- decidingLayer,
703
- decidingId,
704
- startTime
705
- ) : void 0
706
- );
707
- }
708
- const warning = guardVerdict?.warning;
709
- return buildVerdict(
710
- "ALLOW",
711
- void 0,
712
- void 0,
713
- warning,
714
- world,
715
- level,
716
- invariantChecks,
717
- guardsMatched,
718
- rulesMatched,
719
- includeTrace ? buildTrace(
720
- invariantChecks,
721
- safetyChecks,
722
- planCheckResult,
723
- roleChecks,
724
- guardChecks,
725
- kernelRuleChecks,
726
- levelChecks,
727
- decidingLayer,
728
- decidingId,
729
- startTime
730
- ) : void 0
731
- );
732
- }
733
- function checkInvariantCoverage(world, checks) {
734
- const invariants = world.invariants ?? [];
735
- const guards = world.guards?.guards ?? [];
736
- for (const invariant of invariants) {
737
- const coveringGuard = guards.find(
738
- (g) => g.invariant_ref === invariant.id && g.immutable
739
- );
740
- checks.push({
741
- invariantId: invariant.id,
742
- label: invariant.label,
743
- hasGuardCoverage: !!coveringGuard,
744
- coveringGuardId: coveringGuard?.id
745
- });
746
- }
747
- }
748
- function checkSafety(event, eventText, checks) {
749
- const textToCheck = event.intent + (event.payload ? JSON.stringify(event.payload) : "");
750
- for (const { pattern, label } of PROMPT_INJECTION_PATTERNS) {
751
- const triggered = pattern.test(textToCheck);
752
- checks.push({
753
- checkType: "prompt-injection",
754
- triggered,
755
- matchedPattern: triggered ? label : void 0
756
- });
757
- if (triggered) {
758
- for (const remaining of PROMPT_INJECTION_PATTERNS.filter((p) => p.label !== label)) {
759
- checks.push({
760
- checkType: "prompt-injection",
761
- triggered: remaining.pattern.test(textToCheck),
762
- matchedPattern: remaining.pattern.test(textToCheck) ? remaining.label : void 0
763
- });
764
- }
765
- return {
766
- status: "PAUSE",
767
- reason: NEUTRAL_MESSAGES["prompt-injection"],
768
- ruleId: `safety-injection-${label}`
769
- };
770
- }
771
- }
772
- const scopeToCheck = event.scope ?? event.intent;
773
- for (const { pattern, label } of SCOPE_ESCAPE_PATTERNS) {
774
- const triggered = pattern.test(scopeToCheck);
775
- checks.push({
776
- checkType: "scope-escape",
777
- triggered,
778
- matchedPattern: triggered ? label : void 0
779
- });
780
- if (triggered) {
781
- for (const remaining of SCOPE_ESCAPE_PATTERNS.filter((p) => p.label !== label)) {
782
- checks.push({
783
- checkType: "scope-escape",
784
- triggered: remaining.pattern.test(scopeToCheck),
785
- matchedPattern: remaining.pattern.test(scopeToCheck) ? remaining.label : void 0
786
- });
787
- }
788
- return {
789
- status: "PAUSE",
790
- reason: NEUTRAL_MESSAGES["scope-escape"],
791
- ruleId: `safety-scope-${label}`
792
- };
793
- }
794
- }
795
- if (event.direction === "output") {
796
- for (const { pattern, label } of EXECUTION_CLAIM_PATTERNS) {
797
- const triggered = pattern.test(textToCheck);
798
- checks.push({
799
- checkType: "execution-claim",
800
- triggered,
801
- matchedPattern: triggered ? label : void 0
802
- });
803
- if (triggered) {
804
- for (const remaining of EXECUTION_CLAIM_PATTERNS.filter((p) => p.label !== label)) {
805
- checks.push({
806
- checkType: "execution-claim",
807
- triggered: remaining.pattern.test(textToCheck),
808
- matchedPattern: remaining.pattern.test(textToCheck) ? remaining.label : void 0
809
- });
810
- }
811
- return {
812
- status: "PAUSE",
813
- reason: NEUTRAL_MESSAGES["execution-claim"],
814
- ruleId: `safety-execution-claim-${label}`
815
- };
816
- }
817
- }
818
- }
819
- if (event.direction === "input") {
820
- const intentTrimmed = event.intent.trim();
821
- for (const { pattern, label } of EXECUTION_INTENT_PATTERNS) {
822
- const triggered = pattern.test(intentTrimmed);
823
- checks.push({
824
- checkType: "execution-intent",
825
- triggered,
826
- matchedPattern: triggered ? label : void 0
827
- });
828
- if (triggered) {
829
- for (const remaining of EXECUTION_INTENT_PATTERNS.filter((p) => p.label !== label)) {
830
- checks.push({
831
- checkType: "execution-intent",
832
- triggered: remaining.pattern.test(intentTrimmed),
833
- matchedPattern: remaining.pattern.test(intentTrimmed) ? remaining.label : void 0
834
- });
835
- }
836
- return {
837
- status: "PAUSE",
838
- reason: NEUTRAL_MESSAGES["execution-intent"],
839
- ruleId: `safety-execution-intent-${label}`
840
- };
841
- }
842
- }
843
- }
844
- return null;
845
- }
846
- function checkRoleRules(event, eventText, world, checks) {
847
- if (!event.roleId || !world.roles) return null;
848
- const role = world.roles.roles.find((r) => r.id === event.roleId);
849
- if (!role) return null;
850
- if (role.requiresApproval) {
851
- checks.push({
852
- roleId: role.id,
853
- roleName: role.name,
854
- rule: "All actions require approval",
855
- ruleType: "requiresApproval",
856
- matched: true
857
- });
858
- return {
859
- status: "PAUSE",
860
- reason: `Role "${role.name}" requires approval for all actions.`,
861
- ruleId: `role-${role.id}-requires-approval`
862
- };
863
- }
864
- for (const rule of role.cannotDo) {
865
- const matched = matchesKeywords(eventText, rule);
866
- checks.push({
867
- roleId: role.id,
868
- roleName: role.name,
869
- rule,
870
- ruleType: "cannotDo",
871
- matched
872
- });
873
- if (matched) {
874
- return {
875
- status: "BLOCK",
876
- reason: `Role "${role.name}" cannot: ${rule}`,
877
- ruleId: `role-${role.id}-cannotdo`
878
- };
879
- }
880
- }
881
- for (const rule of role.canDo) {
882
- checks.push({
883
- roleId: role.id,
884
- roleName: role.name,
885
- rule,
886
- ruleType: "canDo",
887
- matched: matchesKeywords(eventText, rule)
888
- });
889
- }
890
- return null;
891
- }
892
- function checkGuards(event, eventText, world, checks, guardsMatched) {
893
- if (!world.guards) return null;
894
- const guardsConfig = world.guards;
895
- let warnResult = null;
896
- const compiledPatterns = /* @__PURE__ */ new Map();
897
- for (const [key, def] of Object.entries(guardsConfig.intent_vocabulary)) {
898
- try {
899
- compiledPatterns.set(key, new RegExp(def.pattern, "i"));
900
- } catch {
901
- }
902
- }
903
- const eventTool = (event.tool ?? "").toLowerCase();
904
- for (const guard of guardsConfig.guards) {
905
- if (guard.appliesTo && guard.appliesTo.length > 0) {
906
- const normalizedAppliesTo = guard.appliesTo.map((t) => t.toLowerCase());
907
- if (!normalizedAppliesTo.includes(eventTool)) {
908
- continue;
909
- }
910
- }
911
- const enabled = guard.immutable || guard.default_enabled !== false;
912
- const matchedPatterns = [];
913
- for (const patternKey of guard.intent_patterns) {
914
- const regex = compiledPatterns.get(patternKey);
915
- if (regex?.test(eventText)) {
916
- matchedPatterns.push(patternKey);
917
- }
918
- }
919
- const matched = matchedPatterns.length > 0 && enabled;
920
- let roleGated = false;
921
- if (matched && guard.required_roles && guard.required_roles.length > 0 && event.roleId && guard.required_roles.includes(event.roleId)) {
922
- roleGated = true;
923
- }
924
- checks.push({
925
- guardId: guard.id,
926
- label: guard.label,
927
- category: guard.category,
928
- enabled,
929
- matched: matched && !roleGated,
930
- enforcement: guard.enforcement,
931
- matchedPatterns,
932
- roleGated
933
- });
934
- if (!matched || roleGated) continue;
935
- guardsMatched.push(guard.id);
936
- const actionMode = guard.player_modes?.action ?? guard.enforcement;
937
- const reason = guard.redirect ? `${guard.description} \u2014 ${guard.redirect}` : guard.description;
938
- if (actionMode === "block") {
939
- return { status: "BLOCK", reason, ruleId: `guard-${guard.id}` };
940
- }
941
- if (actionMode === "pause") {
942
- return { status: "PAUSE", reason, ruleId: `guard-${guard.id}` };
943
- }
944
- if (actionMode === "penalize") {
945
- const consequence = guard.consequence ? { ...guard.consequence } : { type: "freeze", rounds: 1, description: `Penalized for violating: ${guard.label}` };
946
- return { status: "PENALIZE", reason, ruleId: `guard-${guard.id}`, consequence };
947
- }
948
- if (actionMode === "reward") {
949
- const reward = guard.reward ? { ...guard.reward } : { type: "boost_influence", magnitude: 0.1, description: `Rewarded for: ${guard.label}` };
950
- return { status: "REWARD", reason, ruleId: `guard-${guard.id}`, reward };
951
- }
952
- if (actionMode === "modify") {
953
- const modifiedTo = guard.modify_to ?? guard.redirect ?? "hold";
954
- return { status: "MODIFY", reason: `${reason} \u2192 Modified to: ${modifiedTo}`, ruleId: `guard-${guard.id}`, modifiedTo };
955
- }
956
- if (actionMode === "neutral") {
957
- return { status: "NEUTRAL", reason, ruleId: `guard-${guard.id}` };
958
- }
959
- if (actionMode === "warn" && !warnResult) {
960
- warnResult = { status: "ALLOW", warning: reason, ruleId: `guard-${guard.id}` };
961
- }
962
- }
963
- return warnResult;
964
- }
965
- function checkKernelRules(eventText, world, checks, rulesMatched) {
966
- if (!world.kernel) return null;
967
- const forbidden = world.kernel.input_boundaries?.forbidden_patterns ?? [];
968
- const output = world.kernel.output_boundaries?.forbidden_patterns ?? [];
969
- for (const rule of forbidden) {
970
- let matched = false;
971
- let matchMethod = "none";
972
- if (rule.pattern) {
973
- try {
974
- matched = new RegExp(rule.pattern, "i").test(eventText);
975
- matchMethod = "pattern";
976
- } catch {
977
- }
978
- }
979
- if (!matched && rule.reason) {
980
- matched = matchesKeywords(eventText, rule.reason);
981
- if (matched) matchMethod = "keyword";
982
- }
983
- checks.push({
984
- ruleId: rule.id,
985
- text: rule.reason,
986
- category: "forbidden",
987
- matched,
988
- matchMethod
989
- });
990
- if (matched) {
991
- rulesMatched.push(rule.id);
992
- if (rule.action === "BLOCK") {
993
- return {
994
- status: "BLOCK",
995
- reason: rule.reason,
996
- ruleId: `kernel-${rule.id}`
997
- };
998
- }
999
- }
1000
- }
1001
- return null;
1002
- }
1003
- function checkLevelConstraints(event, level, checks) {
1004
- if (level === "basic") return null;
1005
- const intent = event.intent.toLowerCase();
1006
- const tool = (event.tool ?? "").toLowerCase();
1007
- const isDelete = intent.includes("delete") || intent.includes("remove") || intent.includes("rm ") || tool === "delete";
1008
- const deleteTriggered = isDelete && levelRequiresConfirmation(level, "delete");
1009
- checks.push({
1010
- checkType: "delete",
1011
- level,
1012
- triggered: deleteTriggered,
1013
- reason: deleteTriggered ? NEUTRAL_MESSAGES["delete"] : void 0
1014
- });
1015
- if (deleteTriggered) {
1016
- return { status: "PAUSE", reason: NEUTRAL_MESSAGES["delete"], ruleId: "level-delete-check" };
1017
- }
1018
- const isExternal = event.scope ? isExternalScope(event.scope) : false;
1019
- const externalTriggered = isExternal && levelRequiresConfirmation(level, "write-external");
1020
- checks.push({
1021
- checkType: "write-external",
1022
- level,
1023
- triggered: externalTriggered,
1024
- reason: externalTriggered ? NEUTRAL_MESSAGES["write-external"] : void 0
1025
- });
1026
- if (externalTriggered) {
1027
- return { status: "PAUSE", reason: NEUTRAL_MESSAGES["write-external"], ruleId: "level-external-write-check" };
1028
- }
1029
- const isNetwork = tool === "http" || tool === "fetch" || tool === "request" || intent.includes("post ") || intent.includes("sending");
1030
- const networkTriggered = isNetwork && levelRequiresConfirmation(level, "network-mutate");
1031
- checks.push({
1032
- checkType: "network-mutate",
1033
- level,
1034
- triggered: networkTriggered,
1035
- reason: networkTriggered ? NEUTRAL_MESSAGES["network-mutate"] : void 0
1036
- });
1037
- if (networkTriggered) {
1038
- return { status: "PAUSE", reason: NEUTRAL_MESSAGES["network-mutate"], ruleId: "level-network-mutate-check" };
1039
- }
1040
- const isCredential = intent.includes("credential") || intent.includes("password") || intent.includes("secret") || intent.includes("api key") || intent.includes("token");
1041
- const credentialTriggered = isCredential && levelRequiresConfirmation(level, "credential-access");
1042
- checks.push({
1043
- checkType: "credential-access",
1044
- level,
1045
- triggered: credentialTriggered,
1046
- reason: credentialTriggered ? NEUTRAL_MESSAGES["credential-access"] : void 0
1047
- });
1048
- if (credentialTriggered) {
1049
- return { status: "PAUSE", reason: NEUTRAL_MESSAGES["credential-access"], ruleId: "level-credential-check" };
1050
- }
1051
- const irreversibleTriggered = !!event.irreversible && level !== "basic";
1052
- checks.push({
1053
- checkType: "irreversible",
1054
- level,
1055
- triggered: irreversibleTriggered,
1056
- reason: irreversibleTriggered ? "This action is marked as irreversible." : void 0
1057
- });
1058
- if (irreversibleTriggered) {
1059
- return {
1060
- status: "PAUSE",
1061
- reason: "This action is marked as irreversible.",
1062
- ruleId: "level-irreversible-check"
1063
- };
1064
- }
1065
- return null;
1066
- }
1067
- function matchesKeywords(eventText, ruleText) {
1068
- return matchesAllKeywords(eventText, ruleText);
1069
- }
1070
- function eventToAllowlistKey(event) {
1071
- return `${(event.tool ?? "*").toLowerCase()}::${event.intent.toLowerCase().trim()}`;
1072
- }
1073
- function buildTrace(invariantChecks, safetyChecks, planCheck, roleChecks, guardChecks, kernelRuleChecks, levelChecks, decidingLayer, decidingId, startTime) {
1074
- const trace = {
1075
- invariantChecks,
1076
- safetyChecks,
1077
- roleChecks,
1078
- guardChecks,
1079
- kernelRuleChecks,
1080
- levelChecks,
1081
- precedenceResolution: {
1082
- decidingLayer,
1083
- decidingId,
1084
- strategy: "first-match-wins",
1085
- chainOrder: [
1086
- "invariant-coverage",
1087
- "session-allowlist",
1088
- "safety-injection",
1089
- "safety-scope-escape",
1090
- "safety-execution-claim",
1091
- "safety-execution-intent",
1092
- "plan-enforcement",
1093
- "role-rules",
1094
- "declarative-guards",
1095
- "kernel-rules",
1096
- "level-constraints",
1097
- "default-allow"
1098
- ]
1099
- },
1100
- durationMs: performance.now() - startTime
1101
- };
1102
- if (planCheck) {
1103
- trace.planCheck = planCheck;
1104
- }
1105
- return trace;
1106
- }
1107
- function buildVerdict(status, reason, ruleId, warning, world, level, invariantChecks, guardsMatched, rulesMatched, trace) {
1108
- const evidence = {
1109
- worldId: world.world.world_id,
1110
- worldName: world.world.name,
1111
- worldVersion: world.world.version,
1112
- evaluatedAt: Date.now(),
1113
- invariantsSatisfied: invariantChecks.filter((c) => c.hasGuardCoverage).length,
1114
- invariantsTotal: invariantChecks.length,
1115
- guardsMatched,
1116
- rulesMatched,
1117
- enforcementLevel: level
1118
- };
1119
- const verdict = {
1120
- status,
1121
- evidence
1122
- };
1123
- if (reason) verdict.reason = reason;
1124
- if (ruleId) verdict.ruleId = ruleId;
1125
- if (warning) verdict.warning = warning;
1126
- if (trace) verdict.trace = trace;
1127
- return verdict;
1128
- }
1129
-
1130
- // src/loader/world-loader.ts
1131
- async function loadWorldFromDirectory(dirPath) {
1132
- const { readFile } = await import("fs/promises");
1133
- const { join } = await import("path");
1134
- const { readdirSync } = await import("fs");
1135
- async function readJson(filename) {
1136
- try {
1137
- const content = await readFile(join(dirPath, filename), "utf-8");
1138
- return JSON.parse(content);
1139
- } catch {
1140
- return void 0;
1141
- }
1142
- }
1143
- const worldJson = await readJson("world.json");
1144
- if (!worldJson) {
1145
- throw new Error(`Cannot read world.json in ${dirPath}`);
1146
- }
1147
- const invariantsJson = await readJson("invariants.json");
1148
- const assumptionsJson = await readJson("assumptions.json");
1149
- const stateSchemaJson = await readJson("state-schema.json");
1150
- const gatesJson = await readJson("gates.json");
1151
- const outcomesJson = await readJson("outcomes.json");
1152
- const guardsJson = await readJson("guards.json");
1153
- const rolesJson = await readJson("roles.json");
1154
- const kernelJson = await readJson("kernel.json");
1155
- const metadataJson = await readJson("metadata.json");
1156
- const rules = [];
1157
- try {
1158
- const rulesDir = join(dirPath, "rules");
1159
- const ruleFiles = readdirSync(rulesDir).filter((f) => f.endsWith(".json")).sort();
1160
- for (const file of ruleFiles) {
1161
- const content = await readFile(join(rulesDir, file), "utf-8");
1162
- rules.push(JSON.parse(content));
1163
- }
1164
- } catch {
1165
- }
1166
- return {
1167
- world: worldJson,
1168
- invariants: invariantsJson?.invariants ?? [],
1169
- assumptions: assumptionsJson ?? { profiles: {}, parameter_definitions: {} },
1170
- stateSchema: stateSchemaJson ?? { variables: {}, presets: {} },
1171
- rules,
1172
- gates: gatesJson ?? {
1173
- viability_classification: [],
1174
- structural_override: { description: "", enforcement: "mandatory" },
1175
- sustainability_threshold: 0,
1176
- collapse_visual: { background: "", text: "", border: "", label: "" }
1177
- },
1178
- outcomes: outcomesJson ?? {
1179
- computed_outcomes: [],
1180
- comparison_layout: { primary_card: "", status_badge: "", structural_indicators: [] }
1181
- },
1182
- guards: guardsJson,
1183
- roles: rolesJson,
1184
- kernel: kernelJson,
1185
- metadata: metadataJson ?? {
1186
- format_version: "1.0.0",
1187
- created_at: "",
1188
- last_modified: "",
1189
- authoring_method: "manual-authoring"
1190
- }
1191
- };
1192
- }
1193
- async function loadWorld(worldPath) {
1194
- const { stat } = await import("fs/promises");
1195
- const info = await stat(worldPath);
1196
- if (info.isDirectory()) {
1197
- return loadWorldFromDirectory(worldPath);
1198
- }
1199
- if (worldPath.endsWith(".nv-world.zip")) {
1200
- throw new Error(".nv-world.zip loading not yet implemented \u2014 use a world directory");
1201
- }
1202
- throw new Error(`Cannot load world from: ${worldPath} \u2014 expected a directory or .nv-world.zip`);
1203
- }
1204
-
1205
- // src/adapters/langchain.ts
1206
- var GovernanceBlockedError2 = class extends GovernanceBlockedError {
1207
- event;
1208
- constructor(verdict, event) {
1209
- super(verdict);
1210
- this.event = event;
1211
- }
1212
- };
1213
- function defaultMapToolCall(toolName, toolInput) {
1214
- return {
1215
- intent: toolName,
1216
- tool: toolName,
1217
- scope: extractScope(toolInput),
1218
- args: toolInput,
1219
- direction: "input"
1220
- };
1221
- }
1222
- var NeuroVerseCallbackHandler = class {
1223
- name = "NeuroVerseGovernance";
1224
- world;
1225
- options;
1226
- engineOptions;
1227
- mapToolCall;
1228
- activePlan;
1229
- constructor(world, options = {}) {
1230
- this.world = world;
1231
- this.options = options;
1232
- this.activePlan = options.plan;
1233
- this.engineOptions = buildEngineOptions(options, this.activePlan);
1234
- this.mapToolCall = options.mapToolCall ?? defaultMapToolCall;
1235
- }
1236
- /**
1237
- * Called before a tool is executed.
1238
- * Evaluates the tool call against the governance world.
1239
- *
1240
- * @throws GovernanceBlockedError if the action is BLOCKED
1241
- * @throws GovernanceBlockedError if the action is PAUSED and onPause returns false
1242
- */
1243
- async handleToolStart(tool, input) {
1244
- let parsedInput;
1245
- try {
1246
- parsedInput = typeof input === "string" ? JSON.parse(input) : input;
1247
- } catch {
1248
- parsedInput = { raw: input };
1249
- }
1250
- const event = this.mapToolCall(tool.name, parsedInput);
1251
- this.engineOptions.plan = this.activePlan;
1252
- const verdict = evaluateGuard(event, this.world, this.engineOptions);
1253
- this.options.onEvaluate?.(verdict, event);
1254
- if (verdict.status === "BLOCK") {
1255
- this.options.onBlock?.(verdict, event);
1256
- throw new GovernanceBlockedError2(verdict, event);
1257
- }
1258
- if (verdict.status === "PAUSE") {
1259
- const approved = await this.options.onPause?.(verdict, event);
1260
- if (!approved) {
1261
- throw new GovernanceBlockedError2(verdict, event);
1262
- }
1263
- }
1264
- if (verdict.status === "ALLOW") {
1265
- trackPlanProgress(event, this, this.options);
1266
- }
1267
- }
1268
- };
1269
- async function createNeuroVerseCallbackHandler(worldPath, options) {
1270
- const world = await loadWorld(worldPath);
1271
- return new NeuroVerseCallbackHandler(world, options);
1272
- }
1273
- function createNeuroVerseCallbackHandlerFromWorld(world, options) {
1274
- return new NeuroVerseCallbackHandler(world, options);
1275
- }
1276
-
1277
- // src/adapters/openai.ts
1278
- var GovernanceBlockedError3 = class extends GovernanceBlockedError {
1279
- toolCallId;
1280
- constructor(verdict, toolCallId) {
1281
- super(verdict);
1282
- this.toolCallId = toolCallId;
1283
- }
1284
- };
1285
- function defaultMapFunctionCall(name, args) {
1286
- return {
1287
- intent: name,
1288
- tool: name,
1289
- scope: extractScope(args),
1290
- args,
1291
- direction: "input"
1292
- };
1293
- }
1294
- var GovernedToolExecutor = class {
1295
- world;
1296
- options;
1297
- engineOptions;
1298
- mapFn;
1299
- blockMsg;
1300
- activePlan;
1301
- constructor(world, options = {}) {
1302
- this.world = world;
1303
- this.options = options;
1304
- this.activePlan = options.plan;
1305
- this.engineOptions = buildEngineOptions(options, this.activePlan);
1306
- this.mapFn = options.mapFunctionCall ?? defaultMapFunctionCall;
1307
- this.blockMsg = options.blockMessage ?? defaultBlockMessage;
1308
- }
1309
- /**
1310
- * Evaluate a single tool call against governance rules.
1311
- * Returns the verdict without executing the tool.
1312
- */
1313
- evaluate(toolCall) {
1314
- let args;
1315
- try {
1316
- args = JSON.parse(toolCall.function.arguments);
1317
- } catch {
1318
- args = { raw: toolCall.function.arguments };
1319
- }
1320
- const event = this.mapFn(toolCall.function.name, args);
1321
- this.engineOptions.plan = this.activePlan;
1322
- const verdict = evaluateGuard(event, this.world, this.engineOptions);
1323
- this.options.onEvaluate?.(verdict, event);
1324
- if (verdict.status === "ALLOW") {
1325
- trackPlanProgress(event, this, this.options);
1326
- }
1327
- return verdict;
1328
- }
1329
- /**
1330
- * Execute a tool call with governance enforcement.
1331
- *
1332
- * If ALLOW: runs the tool and returns the result.
1333
- * If BLOCK: returns a blocked message (no execution).
1334
- * If PAUSE: throws — caller must handle approval flow.
1335
- *
1336
- * @param toolCall - The OpenAI tool call to evaluate
1337
- * @param runner - The actual tool execution function
1338
- * @returns A tool result message ready for the OpenAI API
1339
- */
1340
- async execute(toolCall, runner) {
1341
- const verdict = this.evaluate(toolCall);
1342
- if (verdict.status === "BLOCK") {
1343
- return {
1344
- tool_call_id: toolCall.id,
1345
- role: "tool",
1346
- content: this.blockMsg(verdict),
1347
- _verdict: verdict
1348
- };
1349
- }
1350
- if (verdict.status === "PAUSE") {
1351
- throw new GovernanceBlockedError3(verdict, toolCall.id);
1352
- }
1353
- let args;
1354
- try {
1355
- args = JSON.parse(toolCall.function.arguments);
1356
- } catch {
1357
- args = { raw: toolCall.function.arguments };
1358
- }
1359
- const content = await runner(toolCall.function.name, args);
1360
- return {
1361
- tool_call_id: toolCall.id,
1362
- role: "tool",
1363
- content,
1364
- _verdict: verdict
1365
- };
1366
- }
1367
- };
1368
- async function createGovernedToolExecutor(worldPath, options) {
1369
- const world = await loadWorld(worldPath);
1370
- return new GovernedToolExecutor(world, options);
1371
- }
1372
- function createGovernedToolExecutorFromWorld(world, options) {
1373
- return new GovernedToolExecutor(world, options);
1374
- }
1375
-
1376
- // src/adapters/openclaw.ts
1377
- var GovernanceBlockedError4 = class extends GovernanceBlockedError {
1378
- action;
1379
- constructor(verdict, action) {
1380
- super(verdict);
1381
- this.action = action;
1382
- }
1383
- };
1384
- function defaultMapAction(action, direction) {
1385
- return {
1386
- intent: action.type,
1387
- tool: action.tool ?? action.type,
1388
- args: action.input,
1389
- direction,
1390
- scope: action.input ? extractScope(action.input) : void 0
1391
- };
1392
- }
1393
- var NeuroVersePlugin = class {
1394
- name = "neuroverse-governance";
1395
- world;
1396
- options;
1397
- engineOptions;
1398
- mapAction;
1399
- activePlan;
1400
- constructor(world, options = {}) {
1401
- this.world = world;
1402
- this.options = options;
1403
- this.activePlan = options.plan;
1404
- this.engineOptions = buildEngineOptions(options, this.activePlan);
1405
- this.mapAction = options.mapAction ?? defaultMapAction;
1406
- }
1407
- /**
1408
- * Evaluate an action before execution.
1409
- *
1410
- * @throws GovernanceBlockedError if BLOCKED
1411
- * @returns HookResult with verdict details
1412
- */
1413
- beforeAction(action) {
1414
- const event = this.mapAction(action, "input");
1415
- this.engineOptions.plan = this.activePlan;
1416
- const verdict = evaluateGuard(event, this.world, this.engineOptions);
1417
- const result = {
1418
- allowed: verdict.status === "ALLOW",
1419
- verdict,
1420
- action
1421
- };
1422
- this.options.onEvaluate?.(result);
1423
- if (verdict.status === "BLOCK") {
1424
- throw new GovernanceBlockedError4(verdict, action);
1425
- }
1426
- if (verdict.status === "ALLOW") {
1427
- trackPlanProgress(event, this, this.options);
1428
- }
1429
- return result;
1430
- }
1431
- /**
1432
- * Evaluate an action's output (post-execution governance).
1433
- * Only runs if evaluateOutputs is enabled.
1434
- *
1435
- * @returns HookResult or null if output evaluation is disabled
1436
- */
1437
- afterAction(action, _output) {
1438
- if (!this.options.evaluateOutputs) return null;
1439
- const event = this.mapAction(action, "output");
1440
- const verdict = evaluateGuard(event, this.world, this.engineOptions);
1441
- const result = {
1442
- allowed: verdict.status === "ALLOW",
1443
- verdict,
1444
- action
1445
- };
1446
- this.options.onEvaluate?.(result);
1447
- if (verdict.status === "BLOCK") {
1448
- throw new GovernanceBlockedError4(verdict, action);
1449
- }
1450
- return result;
1451
- }
1452
- /**
1453
- * Get the plugin hooks object for agent.use().
1454
- */
1455
- hooks() {
1456
- return {
1457
- beforeAction: (action) => this.beforeAction(action),
1458
- afterAction: (action, output) => this.afterAction(action, output)
1459
- };
1460
- }
1461
- };
1462
- async function createNeuroVersePlugin(worldPath, options) {
1463
- const world = await loadWorld(worldPath);
1464
- return new NeuroVersePlugin(world, options);
1465
- }
1466
- function createNeuroVersePluginFromWorld(world, options) {
1467
- return new NeuroVersePlugin(world, options);
1468
- }
1469
-
1470
- // src/adapters/express.ts
1471
- function methodToCategory(method) {
1472
- switch (method.toUpperCase()) {
1473
- case "GET":
1474
- case "HEAD":
1475
- case "OPTIONS":
1476
- return "read";
1477
- case "POST":
1478
- case "PUT":
1479
- case "PATCH":
1480
- return "write";
1481
- case "DELETE":
1482
- return "delete";
1483
- default:
1484
- return "other";
1485
- }
1486
- }
1487
- function defaultMapRequest(req) {
1488
- const method = (req.method ?? "GET").toUpperCase();
1489
- const path = req.path ?? req.url ?? "/";
1490
- return {
1491
- intent: `${method} ${path}`,
1492
- tool: "http",
1493
- scope: path,
1494
- actionCategory: methodToCategory(method),
1495
- direction: "input",
1496
- args: {
1497
- method,
1498
- path,
1499
- ...req.params ?? {},
1500
- ...req.query ?? {}
1501
- }
1502
- };
1503
- }
1504
- function defaultOnBlock(verdict, _req, res, statusCode) {
1505
- const body = {
1506
- error: "Governance policy violation",
1507
- reason: verdict.reason ?? "Action not permitted",
1508
- ruleId: verdict.ruleId,
1509
- status: verdict.status
1510
- };
1511
- if (res.status && res.json) {
1512
- res.status(statusCode).json(body);
1513
- } else if (res.send) {
1514
- res.statusCode = statusCode;
1515
- res.send(JSON.stringify(body));
1516
- } else if (res.end) {
1517
- res.statusCode = statusCode;
1518
- res.end();
1519
- }
1520
- }
1521
- async function createGovernanceMiddleware(worldPath, options) {
1522
- const world = await loadWorld(worldPath);
1523
- return createGovernanceMiddlewareFromWorld(world, options);
1524
- }
1525
- function createGovernanceMiddlewareFromWorld(world, options = {}) {
1526
- const engineOptions = {
1527
- trace: options.trace ?? false,
1528
- level: options.level
1529
- };
1530
- const mapRequest = options.mapRequest ?? defaultMapRequest;
1531
- const blockStatusCode = options.blockStatusCode ?? 403;
1532
- return async function neuroVerseGovernance(req, res, next) {
1533
- try {
1534
- const event = mapRequest(req);
1535
- const verdict = evaluateGuard(event, world, engineOptions);
1536
- options.onEvaluate?.(verdict, event, req);
1537
- if (verdict.status === "ALLOW") {
1538
- next();
1539
- return;
1540
- }
1541
- if (verdict.status === "PAUSE") {
1542
- const approved = await options.onPause?.(verdict, req);
1543
- if (approved) {
1544
- next();
1545
- return;
1546
- }
1547
- }
1548
- if (options.onBlock) {
1549
- options.onBlock(verdict, req, res);
1550
- } else {
1551
- defaultOnBlock(verdict, req, res, blockStatusCode);
1552
- }
1553
- } catch (err) {
1554
- next(err);
1555
- }
1556
- };
1557
- }
1558
-
1559
- // src/adapters/autoresearch.ts
1560
- var AutoresearchGovernor = class {
1561
- config;
1562
- state;
1563
- constructor(config) {
1564
- this.config = config;
1565
- this.state = {
1566
- experiments_run: 0,
1567
- best_result: null,
1568
- architectures_tested: [],
1569
- experiment_log: [],
1570
- total_compute_minutes: 0,
1571
- keep_count: 0
1572
- };
1573
- }
1574
- /**
1575
- * Convert an experiment proposal into a GuardEvent for governance evaluation.
1576
- */
1577
- proposalToGuardEvent(proposal) {
1578
- return {
1579
- intent: `run experiment: ${proposal.description}`,
1580
- tool: "experiment_runner",
1581
- scope: "experiment",
1582
- roleId: "experiment_runner",
1583
- direction: "output",
1584
- actionCategory: "shell",
1585
- args: {
1586
- experiment_id: String(proposal.experiment_id),
1587
- architecture: proposal.architecture,
1588
- estimated_minutes: String(proposal.estimated_minutes || 5)
1589
- }
1590
- };
1591
- }
1592
- /**
1593
- * Evaluate an experiment proposal against governance rules.
1594
- * Returns a simplified verdict without requiring the full guard engine.
1595
- */
1596
- evaluateProposal(proposal) {
1597
- const warnings = [];
1598
- const estimatedMinutes = proposal.estimated_minutes || 5;
1599
- if (this.state.total_compute_minutes + estimatedMinutes > this.config.computeBudgetMinutes) {
1600
- return {
1601
- allowed: false,
1602
- reason: `Compute budget exhausted: ${this.state.total_compute_minutes}/${this.config.computeBudgetMinutes} minutes used`,
1603
- warnings
1604
- };
1605
- }
1606
- if (this.config.constraints) {
1607
- for (const constraint of this.config.constraints) {
1608
- const lower = constraint.toLowerCase();
1609
- const archLower = proposal.architecture.toLowerCase();
1610
- const descLower = proposal.description.toLowerCase();
1611
- if (lower.startsWith("no ")) {
1612
- const forbidden = lower.slice(3).trim();
1613
- if (archLower.includes(forbidden) || descLower.includes(forbidden)) {
1614
- return {
1615
- allowed: false,
1616
- reason: `Architecture constraint violated: ${constraint}`,
1617
- warnings
1618
- };
1619
- }
1620
- }
1621
- }
1622
- }
1623
- const failureCount = this.state.experiment_log.filter((e) => !e.success).length;
1624
- if (failureCount > 5) {
1625
- warnings.push(`High failure rate: ${failureCount} failed experiments. Consider investigating root cause.`);
1626
- }
1627
- const recentArchitectures = this.state.experiment_log.slice(-5).map((e) => e.architecture);
1628
- const uniqueRecent = new Set(recentArchitectures).size;
1629
- if (recentArchitectures.length >= 5 && uniqueRecent === 1) {
1630
- warnings.push("Research may be stuck: last 5 experiments used the same architecture.");
1631
- }
1632
- return { allowed: true, reason: "Experiment approved", warnings };
1633
- }
1634
- /**
1635
- * Record an experiment result and update research state.
1636
- */
1637
- recordResult(result) {
1638
- this.state.experiments_run++;
1639
- this.state.total_compute_minutes += result.wall_clock_minutes;
1640
- this.state.experiment_log.push(result);
1641
- if (!this.state.architectures_tested.includes(result.architecture)) {
1642
- this.state.architectures_tested.push(result.architecture);
1643
- }
1644
- if (!result.success) {
1645
- return { kept: false, improvement: null, state: { ...this.state } };
1646
- }
1647
- let kept = false;
1648
- let improvement = null;
1649
- if (this.state.best_result === null) {
1650
- kept = true;
1651
- this.state.best_result = result;
1652
- this.state.keep_count++;
1653
- } else {
1654
- const prev = this.state.best_result.metric_value;
1655
- const curr = result.metric_value;
1656
- if (this.config.optimize === "minimize") {
1657
- kept = curr < prev;
1658
- improvement = kept ? prev - curr : null;
1659
- } else {
1660
- kept = curr > prev;
1661
- improvement = kept ? curr - prev : null;
1662
- }
1663
- if (kept) {
1664
- this.state.best_result = result;
1665
- this.state.keep_count++;
1666
- }
1667
- }
1668
- return { kept, improvement, state: { ...this.state } };
1669
- }
1670
- /**
1671
- * Export current state as a state snapshot compatible with the world file.
1672
- */
1673
- toWorldState() {
1674
- const successfulExperiments = this.state.experiment_log.filter((e) => e.success);
1675
- const failedCount = this.state.experiment_log.filter((e) => !e.success).length;
1676
- const keepRate = this.state.experiments_run > 0 ? Math.round(this.state.keep_count / this.state.experiments_run * 100) : 0;
1677
- let improvementRate = 0;
1678
- if (successfulExperiments.length >= 2) {
1679
- const recent = successfulExperiments.slice(-10);
1680
- let improvements = 0;
1681
- for (let i = 1; i < recent.length; i++) {
1682
- const prev = recent[i - 1].metric_value;
1683
- const curr = recent[i].metric_value;
1684
- if (this.config.optimize === "minimize" ? curr < prev : curr > prev) {
1685
- improvements++;
1686
- }
1687
- }
1688
- improvementRate = Math.round(improvements / (recent.length - 1) * 100);
1689
- }
1690
- return {
1691
- experiments_run: this.state.experiments_run,
1692
- best_metric_value: this.state.best_result?.metric_value ?? (this.config.optimize === "minimize" ? 100 : -1e3),
1693
- keep_rate: keepRate,
1694
- compute_used_minutes: Math.round(this.state.total_compute_minutes),
1695
- compute_budget_minutes: this.config.computeBudgetMinutes,
1696
- failed_experiments: failedCount,
1697
- metric_improvement_rate: improvementRate,
1698
- research_context_drift: 0
1699
- // would need NLP to compute properly
1700
- };
1701
- }
1702
- /**
1703
- * Get a summary of the current research state.
1704
- */
1705
- getSummary() {
1706
- return {
1707
- experiments_run: this.state.experiments_run,
1708
- best_result: this.state.best_result,
1709
- keep_rate: this.state.experiments_run > 0 ? Math.round(this.state.keep_count / this.state.experiments_run * 100) : 0,
1710
- compute_remaining_minutes: this.config.computeBudgetMinutes - this.state.total_compute_minutes,
1711
- architectures_tested: [...this.state.architectures_tested]
1712
- };
1713
- }
1714
- /**
1715
- * Load state from a persisted research context file.
1716
- */
1717
- loadState(state) {
1718
- this.state = { ...state };
1719
- }
1720
- /**
1721
- * Export state for persistence.
1722
- */
1723
- exportState() {
1724
- return { ...this.state };
1725
- }
1726
- };
1727
-
1728
- // src/engine/tool-classifier.ts
1729
- var TOOL_CATEGORY_MAP = {
1730
- // File operations
1731
- read_file: "file_read",
1732
- read: "file_read",
1733
- glob: "file_read",
1734
- grep: "file_read",
1735
- list_files: "file_read",
1736
- write_file: "file_write",
1737
- write: "file_write",
1738
- create_file: "file_write",
1739
- edit_file: "file_write",
1740
- edit: "file_write",
1741
- patch: "file_write",
1742
- delete_file: "file_delete",
1743
- remove_file: "file_delete",
1744
- // Shell
1745
- shell: "shell",
1746
- bash: "shell",
1747
- execute: "shell",
1748
- run_command: "shell",
1749
- terminal: "shell",
1750
- // Git
1751
- git: "git",
1752
- git_commit: "git",
1753
- git_push: "git",
1754
- git_checkout: "git",
1755
- // Network
1756
- http: "network",
1757
- fetch: "network",
1758
- curl: "network",
1759
- web_search: "network",
1760
- // Sub-agents
1761
- sub_agent: "sub_agent",
1762
- spawn_agent: "sub_agent",
1763
- delegate: "sub_agent",
1764
- // Context management
1765
- summarize: "context",
1766
- compress_context: "context"
1767
- };
1768
- function classifyTool(toolName) {
1769
- const normalized = toolName.toLowerCase().replace(/[-\s]/g, "_");
1770
- return TOOL_CATEGORY_MAP[normalized] ?? "unknown";
1771
- }
1772
- var DANGEROUS_SHELL_PATTERNS = [
1773
- { pattern: /rm\s+(-[a-zA-Z]*f[a-zA-Z]*\s+|.*-rf\s+|.*--force)/, label: "force-delete" },
1774
- { pattern: /rm\s+-[a-zA-Z]*r/, label: "recursive-delete" },
1775
- { pattern: />\s*\/dev\/sd/, label: "disk-overwrite" },
1776
- { pattern: /mkfs\./, label: "format-disk" },
1777
- { pattern: /dd\s+if=/, label: "disk-dump" },
1778
- { pattern: /chmod\s+(-R\s+)?777/, label: "world-writable" },
1779
- { pattern: /curl\s+.*\|\s*(bash|sh|zsh)/, label: "pipe-to-shell" },
1780
- { pattern: /wget\s+.*\|\s*(bash|sh|zsh)/, label: "pipe-to-shell" },
1781
- { pattern: /:(){ :\|:& };:/, label: "fork-bomb" },
1782
- { pattern: />\s*\/etc\//, label: "system-config-overwrite" },
1783
- { pattern: /shutdown|reboot|halt|poweroff/, label: "system-shutdown" },
1784
- { pattern: /kill\s+-9\s+1\b/, label: "kill-init" }
1785
- ];
1786
- var DANGEROUS_GIT_PATTERNS = [
1787
- { pattern: /push\s+.*--force/, label: "force-push" },
1788
- { pattern: /push\s+.*-f\b/, label: "force-push" },
1789
- { pattern: /push\s+(origin\s+)?main\b/, label: "push-main" },
1790
- { pattern: /push\s+(origin\s+)?master\b/, label: "push-master" },
1791
- { pattern: /reset\s+--hard/, label: "hard-reset" },
1792
- { pattern: /clean\s+-fd/, label: "clean-force" },
1793
- { pattern: /branch\s+-D/, label: "force-delete-branch" }
1794
- ];
1795
- function isDangerousCommand(command) {
1796
- const matched = DANGEROUS_SHELL_PATTERNS.filter((p) => p.pattern.test(command)).map((p) => p.label);
1797
- return { dangerous: matched.length > 0, labels: matched };
1798
- }
1799
- function isDangerousGitCommand(command) {
1800
- const matched = DANGEROUS_GIT_PATTERNS.filter((p) => p.pattern.test(command)).map((p) => p.label);
1801
- return { dangerous: matched.length > 0, labels: matched };
1802
- }
1803
- function assessRiskLevel(category) {
1804
- if (category === "file_read" || category === "context") return "low";
1805
- if (category === "file_write" || category === "sub_agent") return "medium";
1806
- if (category === "shell" || category === "file_delete" || category === "git" || category === "network") return "high";
1807
- return void 0;
1808
- }
1809
- function categoryToActionCategory(category) {
1810
- if (category === "file_read" || category === "context") return "read";
1811
- if (category === "file_write") return "write";
1812
- if (category === "file_delete") return "delete";
1813
- if (category === "shell") return "shell";
1814
- if (category === "network") return "network";
1815
- return "other";
1816
- }
1817
-
1818
- // src/adapters/deep-agents.ts
1819
- var GovernanceBlockedError5 = class extends GovernanceBlockedError {
1820
- toolCall;
1821
- category;
1822
- constructor(verdict, toolCall, category) {
1823
- super(verdict);
1824
- this.toolCall = toolCall;
1825
- this.category = category;
1826
- }
1827
- };
1828
- function defaultMapToolCall2(toolCall) {
1829
- const category = classifyTool(toolCall.tool);
1830
- const args = toolCall.args;
1831
- const scope = extractScope(args);
1832
- let intent = toolCall.tool;
1833
- if (category === "shell" && typeof args.command === "string") {
1834
- intent = `shell: ${args.command}`;
1835
- } else if (category === "git" && typeof args.command === "string") {
1836
- intent = `git ${args.command}`;
1837
- } else if (category === "file_write" && scope) {
1838
- intent = `write ${scope}`;
1839
- } else if (category === "file_delete" && scope) {
1840
- intent = `delete ${scope}`;
1841
- }
1842
- const riskLevel = assessRiskLevel(category);
1843
- let irreversible = false;
1844
- if (category === "shell" && typeof args.command === "string") {
1845
- irreversible = DANGEROUS_SHELL_PATTERNS.some((p) => p.pattern.test(args.command));
1846
- } else if (category === "git" && typeof args.command === "string") {
1847
- irreversible = DANGEROUS_GIT_PATTERNS.some((p) => p.pattern.test(args.command));
1848
- } else if (category === "file_delete") {
1849
- irreversible = true;
1850
- }
1851
- return {
1852
- intent,
1853
- tool: toolCall.tool,
1854
- scope,
1855
- args,
1856
- direction: "input",
1857
- actionCategory: categoryToActionCategory(category),
1858
- riskLevel,
1859
- irreversible
1860
- };
1861
- }
1862
- var DeepAgentsGuard = class {
1863
- name = "neuroverse-deep-agents-guard";
1864
- world;
1865
- options;
1866
- engineOptions;
1867
- mapToolCall;
1868
- activePlan;
1869
- constructor(world, options = {}) {
1870
- this.world = world;
1871
- this.options = options;
1872
- this.activePlan = options.plan;
1873
- this.engineOptions = buildEngineOptions(options, this.activePlan);
1874
- this.mapToolCall = options.mapToolCall ?? defaultMapToolCall2;
1875
- }
1876
- /**
1877
- * Evaluate a tool call against governance rules.
1878
- * Returns the result without side effects.
1879
- */
1880
- evaluate(toolCall) {
1881
- const event = this.mapToolCall(toolCall);
1882
- this.engineOptions.plan = this.activePlan;
1883
- const verdict = evaluateGuard(event, this.world, this.engineOptions);
1884
- const category = classifyTool(toolCall.tool);
1885
- const result = {
1886
- allowed: verdict.status === "ALLOW",
1887
- verdict,
1888
- toolCall,
1889
- category
1890
- };
1891
- this.options.onEvaluate?.(result);
1892
- if (verdict.status === "ALLOW" && this.activePlan) {
1893
- this.trackPlanProgressInternal(event);
1894
- }
1895
- return result;
1896
- }
1897
- /**
1898
- * Evaluate and enforce governance on a tool call.
1899
- *
1900
- * @throws GovernanceBlockedError if BLOCKED
1901
- * @throws GovernanceBlockedError if PAUSED and onPause returns false
1902
- * @returns DeepAgentsGuardResult on ALLOW
1903
- */
1904
- async enforce(toolCall) {
1905
- const result = this.evaluate(toolCall);
1906
- if (result.verdict.status === "BLOCK") {
1907
- this.options.onBlock?.(result);
1908
- throw new GovernanceBlockedError5(result.verdict, toolCall, result.category);
1909
- }
1910
- if (result.verdict.status === "PAUSE") {
1911
- const approved = await this.options.onPause?.(result);
1912
- if (!approved) {
1913
- throw new GovernanceBlockedError5(result.verdict, toolCall, result.category);
1914
- }
1915
- }
1916
- return result;
1917
- }
1918
- /**
1919
- * Evaluate and execute a tool call with governance enforcement.
1920
- *
1921
- * If ALLOW: runs the executor and returns its result.
1922
- * If BLOCK: returns a governance-blocked message.
1923
- * If PAUSE: calls onPause; blocks if not approved.
1924
- *
1925
- * @param toolCall - The Deep Agents tool call to evaluate
1926
- * @param executor - The actual tool execution function
1927
- * @returns The tool execution result or a blocked message
1928
- */
1929
- async execute(toolCall, executor) {
1930
- const guardResult = this.evaluate(toolCall);
1931
- if (guardResult.verdict.status === "BLOCK") {
1932
- this.options.onBlock?.(guardResult);
1933
- return {
1934
- blocked: true,
1935
- verdict: guardResult.verdict,
1936
- reason: guardResult.verdict.reason ?? "Action blocked by governance policy."
1937
- };
1938
- }
1939
- if (guardResult.verdict.status === "PAUSE") {
1940
- const approved = await this.options.onPause?.(guardResult);
1941
- if (!approved) {
1942
- return {
1943
- blocked: true,
1944
- verdict: guardResult.verdict,
1945
- reason: guardResult.verdict.reason ?? "Action requires approval."
1946
- };
1947
- }
1948
- }
1949
- const result = await executor(toolCall);
1950
- return { result, verdict: guardResult.verdict };
1951
- }
1952
- /**
1953
- * Returns a middleware function compatible with Deep Agents' tool pipeline.
1954
- *
1955
- * The middleware intercepts tool calls before execution:
1956
- * agent.use(guard.middleware());
1957
- */
1958
- middleware() {
1959
- return async (toolCall, next) => {
1960
- await this.enforce(toolCall);
1961
- return next();
1962
- };
1963
- }
1964
- /**
1965
- * Returns a callback-handler-style object for LangChain integration.
1966
- * Compatible with Deep Agents' callback system.
1967
- */
1968
- callbacks() {
1969
- return {
1970
- handleToolStart: async (tool, input) => {
1971
- let parsedInput;
1972
- try {
1973
- parsedInput = typeof input === "string" ? JSON.parse(input) : input;
1974
- } catch {
1975
- parsedInput = { raw: input };
1976
- }
1977
- await this.enforce({ tool: tool.name, args: parsedInput });
1978
- }
1979
- };
1980
- }
1981
- /**
1982
- * Check if a shell command contains dangerous patterns.
1983
- * Useful for pre-screening before full governance evaluation.
1984
- */
1985
- static isDangerousCommand(command) {
1986
- return isDangerousCommand(command);
1987
- }
1988
- /**
1989
- * Check if a git command contains dangerous patterns.
1990
- */
1991
- static isDangerousGitCommand(command) {
1992
- return isDangerousGitCommand(command);
1993
- }
1994
- /**
1995
- * Classify a tool name into a category.
1996
- */
1997
- static classifyTool(toolName) {
1998
- return classifyTool(toolName);
1999
- }
2000
- // ─── Private ──────────────────────────────────────────────────────────────
2001
- trackPlanProgressInternal(event) {
2002
- trackPlanProgress(event, this, this.options);
2003
- }
2004
- };
2005
- async function createDeepAgentsGuard(worldPath, options) {
2006
- const world = await loadWorld(worldPath);
2007
- return new DeepAgentsGuard(world, options);
2008
- }
2009
- function createDeepAgentsGuardFromWorld(world, options) {
2010
- return new DeepAgentsGuard(world, options);
2011
- }
2012
- // Annotate the CommonJS export names for ESM import in node:
2013
- 0 && (module.exports = {
2014
- AutoresearchGovernor,
2015
- DeepAgentsGovernanceBlockedError,
2016
- DeepAgentsGuard,
2017
- GovernanceBlockedError,
2018
- GovernedToolExecutor,
2019
- LangChainGovernanceBlockedError,
2020
- NeuroVerseCallbackHandler,
2021
- NeuroVersePlugin,
2022
- OpenAIGovernanceBlockedError,
2023
- OpenClawGovernanceBlockedError,
2024
- buildEngineOptions,
2025
- createDeepAgentsGuard,
2026
- createDeepAgentsGuardFromWorld,
2027
- createGovernanceMiddleware,
2028
- createGovernanceMiddlewareFromWorld,
2029
- createGovernedToolExecutor,
2030
- createGovernedToolExecutorFromWorld,
2031
- createNeuroVerseCallbackHandler,
2032
- createNeuroVerseCallbackHandlerFromWorld,
2033
- createNeuroVersePlugin,
2034
- createNeuroVersePluginFromWorld,
2035
- defaultBlockMessage,
2036
- extractScope,
2037
- trackPlanProgress
2038
- });