@neuroverseos/governance 0.3.0 → 0.3.3

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 (126) hide show
  1. package/.well-known/ai-plugin.json +34 -9
  2. package/AGENTS.md +72 -24
  3. package/README.md +352 -237
  4. package/dist/adapters/autoresearch.cjs +1152 -3
  5. package/dist/adapters/autoresearch.d.cts +11 -3
  6. package/dist/adapters/autoresearch.d.ts +11 -3
  7. package/dist/adapters/autoresearch.js +9 -4
  8. package/dist/adapters/deep-agents.cjs +1528 -0
  9. package/dist/adapters/deep-agents.d.cts +181 -0
  10. package/dist/adapters/deep-agents.d.ts +181 -0
  11. package/dist/adapters/deep-agents.js +17 -0
  12. package/dist/adapters/express.cjs +171 -32
  13. package/dist/adapters/express.d.cts +1 -1
  14. package/dist/adapters/express.d.ts +1 -1
  15. package/dist/adapters/express.js +5 -5
  16. package/dist/adapters/index.cjs +564 -121
  17. package/dist/adapters/index.d.cts +3 -1
  18. package/dist/adapters/index.d.ts +3 -1
  19. package/dist/adapters/index.js +38 -16
  20. package/dist/adapters/langchain.cjs +217 -57
  21. package/dist/adapters/langchain.d.cts +5 -5
  22. package/dist/adapters/langchain.d.ts +5 -5
  23. package/dist/adapters/langchain.js +6 -5
  24. package/dist/adapters/openai.cjs +219 -59
  25. package/dist/adapters/openai.d.cts +5 -5
  26. package/dist/adapters/openai.d.ts +5 -5
  27. package/dist/adapters/openai.js +6 -5
  28. package/dist/adapters/openclaw.cjs +217 -57
  29. package/dist/adapters/openclaw.d.cts +6 -6
  30. package/dist/adapters/openclaw.d.ts +6 -6
  31. package/dist/adapters/openclaw.js +6 -5
  32. package/dist/add-ROOZLU62.js +314 -0
  33. package/dist/behavioral-MJO34S6Q.js +118 -0
  34. package/dist/{bootstrap-GXVDZNF7.js → bootstrap-CQRZVOXK.js} +6 -4
  35. package/dist/bootstrap-emitter-Q7UIJZ2O.js +7 -0
  36. package/dist/bootstrap-parser-EEF36XDU.js +7 -0
  37. package/dist/browser.global.js +941 -0
  38. package/dist/{build-P42YFKQV.js → build-QKOBBC23.js} +7 -5
  39. package/dist/{chunk-COT5XS4V.js → chunk-3WQLXYTP.js} +17 -35
  40. package/dist/{chunk-ER62HNGF.js → chunk-4FLICVVA.js} +17 -37
  41. package/dist/chunk-5TPFNWRU.js +215 -0
  42. package/dist/chunk-5U2MQO5P.js +57 -0
  43. package/dist/{chunk-NF5POFCI.js → chunk-6S5CFQXY.js} +6 -4
  44. package/dist/{chunk-QPASI2BR.js → chunk-A7GKPPU7.js} +49 -10
  45. package/dist/{chunk-OGL7QXZS.js → chunk-B6OXJLJ5.js} +17 -3
  46. package/dist/{chunk-2PQU3VAN.js → chunk-BNKJPUPQ.js} +17 -35
  47. package/dist/chunk-BQZMOEML.js +43 -0
  48. package/dist/chunk-CNSO6XW5.js +207 -0
  49. package/dist/{chunk-JZPQGIKR.js → chunk-CTZHONLA.js} +65 -9
  50. package/dist/chunk-D2UCV5AK.js +326 -0
  51. package/dist/{chunk-XPDMYECO.js → chunk-EMQDLDAF.js} +1 -185
  52. package/dist/{chunk-GR6DGCZ2.js → chunk-F66BVUYB.js} +3 -3
  53. package/dist/{chunk-2NICNKOM.js → chunk-G7DJ6VOD.js} +5 -4
  54. package/dist/{chunk-4A7LISES.js → chunk-IS4WUH6Y.js} +45 -6
  55. package/dist/{chunk-MWDQ4MJB.js → chunk-MH7BT4VH.js} +5 -1
  56. package/dist/chunk-O5ABKEA7.js +304 -0
  57. package/dist/chunk-PVTQQS3Y.js +186 -0
  58. package/dist/{chunk-4QXB6PEO.js → chunk-QLPTHTVB.js} +37 -16
  59. package/dist/chunk-QWGCMQQD.js +16 -0
  60. package/dist/{chunk-T5EUJQE5.js → chunk-QXBFT7NI.js} +31 -2
  61. package/dist/{chunk-PDOZHZWL.js → chunk-TG6SEF24.js} +25 -4
  62. package/dist/chunk-U6U7EJZL.js +177 -0
  63. package/dist/{chunk-4JRYGIO7.js → chunk-W7LLXRGY.js} +110 -7
  64. package/dist/{chunk-BUWWN2NX.js → chunk-ZJTDUCC2.js} +9 -7
  65. package/dist/{chunk-FYS2CBUW.js → chunk-ZWI3NIXK.js} +10 -0
  66. package/dist/cli/neuroverse.cjs +5091 -2348
  67. package/dist/cli/neuroverse.js +52 -21
  68. package/dist/cli/plan.cjs +881 -41
  69. package/dist/cli/plan.js +7 -15
  70. package/dist/cli/run.cjs +289 -34
  71. package/dist/cli/run.js +4 -4
  72. package/dist/{configure-ai-TK67ZWZL.js → configure-ai-6TZ3MCSI.js} +1 -1
  73. package/dist/decision-flow-M63D47LO.js +61 -0
  74. package/dist/demo-G43RLCPK.js +469 -0
  75. package/dist/{derive-TLIV4OOU.js → derive-FJZVIPUZ.js} +5 -4
  76. package/dist/{doctor-XPDLEYXN.js → doctor-6BC6X2VO.js} +6 -4
  77. package/dist/equity-penalties-SG5IZQ7I.js +244 -0
  78. package/dist/{explain-IDCRWMPX.js → explain-RHBU2GBR.js} +6 -25
  79. package/dist/{guard-RV65TT4L.js → guard-AJCCGZMF.js} +8 -12
  80. package/dist/{guard-contract-WZx__PmU.d.cts → guard-contract-DqFcTScd.d.cts} +117 -5
  81. package/dist/{guard-contract-WZx__PmU.d.ts → guard-contract-DqFcTScd.d.ts} +117 -5
  82. package/dist/{guard-engine-JLTUARGU.js → guard-engine-PNR6MHCM.js} +3 -3
  83. package/dist/{impact-XPECYRLH.js → impact-3XVDSCBU.js} +5 -5
  84. package/dist/{improve-GPUBKTEA.js → improve-TQP4ECSY.js} +7 -26
  85. package/dist/index.cjs +5597 -4279
  86. package/dist/index.d.cts +597 -18
  87. package/dist/index.d.ts +597 -18
  88. package/dist/index.js +134 -41
  89. package/dist/{infer-world-7GVZWFX4.js → infer-world-IFXCACJ5.js} +1 -1
  90. package/dist/{init-PKPIYHYE.js → init-FYPV4SST.js} +1 -1
  91. package/dist/{init-world-VWMQZQC7.js → init-world-TI7ARHBT.js} +1 -1
  92. package/dist/mcp-server-5Y3ZM7TV.js +13 -0
  93. package/dist/{model-adapter-BB7G4MFI.js → model-adapter-VXEKB4LS.js} +1 -1
  94. package/dist/{playground-E664U4T6.js → playground-VZBNPPBO.js} +29 -19
  95. package/dist/{redteam-Z7WREJ44.js → redteam-MZPZD3EF.js} +4 -4
  96. package/dist/session-JYOARW54.js +15 -0
  97. package/dist/shared-7RLUHNMU.js +16 -0
  98. package/dist/shared-B8dvUUD8.d.cts +60 -0
  99. package/dist/shared-Dr5Wiay8.d.ts +60 -0
  100. package/dist/{simulate-VDOYQFRO.js → simulate-LJXYBC6M.js} +8 -33
  101. package/dist/{test-OGXJK4QU.js → test-BOOR4A5F.js} +4 -4
  102. package/dist/{trace-JVF67VR3.js → trace-PKV4KX56.js} +4 -4
  103. package/dist/{validate-LLBWVPGV.js → validate-RALX7CZS.js} +2 -2
  104. package/dist/{validate-engine-UIABSIHD.js → validate-engine-7ZXFVGF2.js} +1 -1
  105. package/dist/viz/assets/index-B8SaeJZZ.js +23 -0
  106. package/dist/viz/index.html +23 -0
  107. package/dist/{world-LAXO6DOX.js → world-BIP4GZBZ.js} +9 -11
  108. package/dist/world-loader-Y6HMQH2D.js +13 -0
  109. package/dist/worlds/coding-agent.nv-world.md +211 -0
  110. package/dist/worlds/research-agent.nv-world.md +169 -0
  111. package/dist/worlds/social-media.nv-world.md +198 -0
  112. package/dist/worlds/trading-agent.nv-world.md +218 -0
  113. package/examples/social-media-sim/bridge.py +209 -0
  114. package/examples/social-media-sim/simulation.py +927 -0
  115. package/package.json +30 -4
  116. package/policies/content-moderation-rules.txt +8 -0
  117. package/policies/marketing-rules.txt +8 -0
  118. package/policies/science-research-rules.txt +11 -0
  119. package/policies/social-media-rules.txt +7 -0
  120. package/policies/strict-rules.txt +8 -0
  121. package/policies/trading-rules.txt +8 -0
  122. package/simulate.html +1567 -0
  123. package/dist/chunk-YZFATT7X.js +0 -9
  124. package/dist/mcp-server-FPVSU32Z.js +0 -13
  125. package/dist/session-EKTRSR7C.js +0 -14
  126. package/dist/world-loader-HMPTOEA2.js +0 -9
@@ -30,24 +30,34 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/adapters/openclaw.ts
31
31
  var openclaw_exports = {};
32
32
  __export(openclaw_exports, {
33
- GovernanceBlockedError: () => GovernanceBlockedError,
33
+ GovernanceBlockedError: () => GovernanceBlockedError2,
34
34
  NeuroVersePlugin: () => NeuroVersePlugin,
35
35
  createNeuroVersePlugin: () => createNeuroVersePlugin,
36
36
  createNeuroVersePluginFromWorld: () => createNeuroVersePluginFromWorld
37
37
  });
38
38
  module.exports = __toCommonJS(openclaw_exports);
39
39
 
40
- // src/engine/plan-engine.ts
41
- function keywordMatch(eventText, step) {
42
- const stepText = [
43
- step.label,
44
- step.description ?? "",
45
- ...step.tags ?? []
40
+ // src/engine/text-utils.ts
41
+ function normalizeEventText(event) {
42
+ return [
43
+ event.intent,
44
+ event.tool ?? "",
45
+ event.scope ?? ""
46
46
  ].join(" ").toLowerCase();
47
- const keywords = stepText.split(/\s+/).filter((w) => w.length > 3);
47
+ }
48
+ function extractKeywords(text, minLength = 3) {
49
+ return text.toLowerCase().split(/\s+/).filter((w) => w.length > minLength);
50
+ }
51
+ function matchesAllKeywords(eventText, ruleText) {
52
+ const keywords = extractKeywords(ruleText);
53
+ if (keywords.length === 0) return false;
54
+ return keywords.every((kw) => eventText.includes(kw));
55
+ }
56
+ function matchesKeywordThreshold(eventText, ruleText, threshold = 0.5) {
57
+ const keywords = extractKeywords(ruleText);
48
58
  if (keywords.length === 0) return false;
49
59
  const matched = keywords.filter((kw) => eventText.includes(kw));
50
- return matched.length >= Math.ceil(keywords.length * 0.5);
60
+ return matched.length >= Math.ceil(keywords.length * threshold);
51
61
  }
52
62
  function tokenSimilarity(a, b) {
53
63
  const tokensA = new Set(a.toLowerCase().split(/\s+/).filter((w) => w.length > 2));
@@ -60,6 +70,19 @@ function tokenSimilarity(a, b) {
60
70
  const union = (/* @__PURE__ */ new Set([...tokensA, ...tokensB])).size;
61
71
  return union > 0 ? intersection / union : 0;
62
72
  }
73
+
74
+ // src/engine/plan-engine.ts
75
+ function keywordMatch(eventText, step) {
76
+ const stepText = [
77
+ step.label,
78
+ step.description ?? "",
79
+ ...step.tags ?? []
80
+ ].join(" ");
81
+ return matchesKeywordThreshold(eventText, stepText, 0.5);
82
+ }
83
+ function tokenSimilarity2(a, b) {
84
+ return tokenSimilarity(a, b);
85
+ }
63
86
  function findMatchingStep(eventText, event, steps) {
64
87
  const pendingOrActive = steps.filter((s) => s.status === "pending" || s.status === "active");
65
88
  if (pendingOrActive.length === 0) {
@@ -78,7 +101,7 @@ function findMatchingStep(eventText, event, steps) {
78
101
  let bestScore = 0;
79
102
  for (const step of pendingOrActive) {
80
103
  const stepText = [step.label, step.description ?? "", ...step.tags ?? []].join(" ");
81
- const score = tokenSimilarity(intentText, stepText);
104
+ const score = tokenSimilarity2(intentText, stepText);
82
105
  if (score > bestScore) {
83
106
  bestScore = score;
84
107
  bestStep = step;
@@ -119,7 +142,7 @@ function checkConstraints(event, eventText, constraints) {
119
142
  continue;
120
143
  }
121
144
  if (constraint.type === "scope" && constraint.trigger) {
122
- const keywords = constraint.trigger.split(/\s+/).filter((w) => w.length > 3);
145
+ const keywords = extractKeywords(constraint.trigger);
123
146
  const violated = keywords.length > 0 && keywords.every((kw) => eventText.includes(kw));
124
147
  checks.push({
125
148
  constraintId: constraint.id,
@@ -200,11 +223,7 @@ function evaluatePlan(event, plan) {
200
223
  progress
201
224
  };
202
225
  }
203
- const eventText = [
204
- event.intent,
205
- event.tool ?? "",
206
- event.scope ?? ""
207
- ].join(" ").toLowerCase();
226
+ const eventText = normalizeEventText(event);
208
227
  const { matched, closest, closestScore } = findMatchingStep(eventText, event, plan.steps);
209
228
  if (!matched) {
210
229
  return {
@@ -245,7 +264,7 @@ function evaluatePlan(event, plan) {
245
264
  };
246
265
  }
247
266
  function buildPlanCheck(event, plan, verdict) {
248
- const eventText = [event.intent, event.tool ?? "", event.scope ?? ""].join(" ").toLowerCase();
267
+ const eventText = normalizeEventText(event);
249
268
  const { matched, closest, closestScore } = findMatchingStep(eventText, event, plan.steps);
250
269
  const { checks: constraintChecks } = checkConstraints(event, eventText, plan.constraints);
251
270
  const progress = getPlanProgress(plan);
@@ -347,11 +366,49 @@ function isExternalScope(scope) {
347
366
  ];
348
367
  return !internalPatterns.some((p) => p.test(scope));
349
368
  }
369
+ var MAX_INPUT_LENGTH = 1e5;
350
370
  function evaluateGuard(event, world, options = {}) {
351
371
  const startTime = performance.now();
352
372
  const level = options.level ?? "standard";
353
373
  const includeTrace = options.trace ?? false;
354
- const eventText = (event.intent + " " + (event.tool ?? "") + " " + (event.scope ?? "")).toLowerCase();
374
+ if (!event.intent || typeof event.intent !== "string") {
375
+ return {
376
+ status: "BLOCK",
377
+ reason: "GuardEvent.intent is required and must be a string",
378
+ ruleId: "safety-input-validation",
379
+ evidence: {
380
+ worldId: world.world?.world_id ?? "",
381
+ worldName: world.world?.name ?? "",
382
+ worldVersion: world.world?.version ?? "",
383
+ evaluatedAt: Date.now(),
384
+ invariantsSatisfied: 0,
385
+ invariantsTotal: 0,
386
+ guardsMatched: [],
387
+ rulesMatched: [],
388
+ enforcementLevel: level
389
+ }
390
+ };
391
+ }
392
+ const inputLength = event.intent.length + (event.tool?.length ?? 0) + (event.scope?.length ?? 0) + (event.payload ? JSON.stringify(event.payload).length : 0);
393
+ if (inputLength > MAX_INPUT_LENGTH) {
394
+ return {
395
+ status: "BLOCK",
396
+ reason: `Input exceeds maximum allowed length (${MAX_INPUT_LENGTH} characters)`,
397
+ ruleId: "safety-input-length",
398
+ evidence: {
399
+ worldId: world.world?.world_id ?? "",
400
+ worldName: world.world?.name ?? "",
401
+ worldVersion: world.world?.version ?? "",
402
+ evaluatedAt: Date.now(),
403
+ invariantsSatisfied: 0,
404
+ invariantsTotal: 0,
405
+ guardsMatched: [],
406
+ rulesMatched: [],
407
+ enforcementLevel: level
408
+ }
409
+ };
410
+ }
411
+ const eventText = normalizeEventText(event);
355
412
  const invariantChecks = [];
356
413
  const safetyChecks = [];
357
414
  let planCheckResult;
@@ -364,6 +421,43 @@ function evaluateGuard(event, world, options = {}) {
364
421
  const guardsMatched = [];
365
422
  const rulesMatched = [];
366
423
  checkInvariantCoverage(world, invariantChecks);
424
+ if (event.roleId && options.agentStates) {
425
+ const agentState = options.agentStates.get(event.roleId);
426
+ if (agentState && agentState.cooldownRemaining > 0) {
427
+ decidingLayer = "safety";
428
+ decidingId = `penalize-cooldown-${event.roleId}`;
429
+ const verdict = buildVerdict(
430
+ "PENALIZE",
431
+ `Agent "${event.roleId}" is frozen for ${agentState.cooldownRemaining} more round(s) due to prior penalty.`,
432
+ `penalize-cooldown-${event.roleId}`,
433
+ void 0,
434
+ world,
435
+ level,
436
+ invariantChecks,
437
+ guardsMatched,
438
+ rulesMatched,
439
+ includeTrace ? buildTrace(
440
+ invariantChecks,
441
+ safetyChecks,
442
+ planCheckResult,
443
+ roleChecks,
444
+ guardChecks,
445
+ kernelRuleChecks,
446
+ levelChecks,
447
+ decidingLayer,
448
+ decidingId,
449
+ startTime
450
+ ) : void 0
451
+ );
452
+ verdict.intentRecord = {
453
+ originalIntent: event.intent,
454
+ finalAction: "blocked (agent frozen)",
455
+ enforcement: "PENALIZE",
456
+ consequence: { type: "freeze", rounds: agentState.cooldownRemaining, description: "Agent still in cooldown from prior penalty" }
457
+ };
458
+ return verdict;
459
+ }
460
+ }
367
461
  if (options.sessionAllowlist) {
368
462
  const key = eventToAllowlistKey(event);
369
463
  if (options.sessionAllowlist.has(key)) {
@@ -491,7 +585,16 @@ function evaluateGuard(event, world, options = {}) {
491
585
  if (guardVerdict.status !== "ALLOW") {
492
586
  decidingLayer = "guard";
493
587
  decidingId = guardVerdict.ruleId;
494
- return buildVerdict(
588
+ const intentRecord = {
589
+ originalIntent: event.intent,
590
+ 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",
591
+ ruleApplied: guardVerdict.ruleId,
592
+ enforcement: guardVerdict.status,
593
+ modifiedTo: guardVerdict.modifiedTo,
594
+ consequence: guardVerdict.consequence,
595
+ reward: guardVerdict.reward
596
+ };
597
+ const verdict = buildVerdict(
495
598
  guardVerdict.status,
496
599
  guardVerdict.reason,
497
600
  guardVerdict.ruleId,
@@ -514,6 +617,10 @@ function evaluateGuard(event, world, options = {}) {
514
617
  startTime
515
618
  ) : void 0
516
619
  );
620
+ verdict.intentRecord = intentRecord;
621
+ if (guardVerdict.consequence) verdict.consequence = guardVerdict.consequence;
622
+ if (guardVerdict.reward) verdict.reward = guardVerdict.reward;
623
+ return verdict;
517
624
  }
518
625
  }
519
626
  const kernelVerdict = checkKernelRules(eventText, world, kernelRuleChecks, rulesMatched);
@@ -808,6 +915,21 @@ function checkGuards(event, eventText, world, checks, guardsMatched) {
808
915
  if (actionMode === "pause") {
809
916
  return { status: "PAUSE", reason, ruleId: `guard-${guard.id}` };
810
917
  }
918
+ if (actionMode === "penalize") {
919
+ const consequence = guard.consequence ? { ...guard.consequence } : { type: "freeze", rounds: 1, description: `Penalized for violating: ${guard.label}` };
920
+ return { status: "PENALIZE", reason, ruleId: `guard-${guard.id}`, consequence };
921
+ }
922
+ if (actionMode === "reward") {
923
+ const reward = guard.reward ? { ...guard.reward } : { type: "boost_influence", magnitude: 0.1, description: `Rewarded for: ${guard.label}` };
924
+ return { status: "REWARD", reason, ruleId: `guard-${guard.id}`, reward };
925
+ }
926
+ if (actionMode === "modify") {
927
+ const modifiedTo = guard.modify_to ?? guard.redirect ?? "hold";
928
+ return { status: "MODIFY", reason: `${reason} \u2192 Modified to: ${modifiedTo}`, ruleId: `guard-${guard.id}`, modifiedTo };
929
+ }
930
+ if (actionMode === "neutral") {
931
+ return { status: "NEUTRAL", reason, ruleId: `guard-${guard.id}` };
932
+ }
811
933
  if (actionMode === "warn" && !warnResult) {
812
934
  warnResult = { status: "ALLOW", warning: reason, ruleId: `guard-${guard.id}` };
813
935
  }
@@ -917,9 +1039,7 @@ function checkLevelConstraints(event, level, checks) {
917
1039
  return null;
918
1040
  }
919
1041
  function matchesKeywords(eventText, ruleText) {
920
- const keywords = ruleText.toLowerCase().split(/\s+/).filter((w) => w.length > 3);
921
- if (keywords.length === 0) return false;
922
- return keywords.every((kw) => eventText.includes(kw));
1042
+ return matchesAllKeywords(eventText, ruleText);
923
1043
  }
924
1044
  function eventToAllowlistKey(event) {
925
1045
  return `${(event.tool ?? "*").toLowerCase()}::${event.intent.toLowerCase().trim()}`;
@@ -987,10 +1107,18 @@ async function loadWorldFromDirectory(dirPath) {
987
1107
  const { join } = await import("path");
988
1108
  const { readdirSync } = await import("fs");
989
1109
  async function readJson(filename) {
1110
+ const filePath = join(dirPath, filename);
990
1111
  try {
991
- const content = await readFile(join(dirPath, filename), "utf-8");
1112
+ const content = await readFile(filePath, "utf-8");
992
1113
  return JSON.parse(content);
993
- } catch {
1114
+ } catch (err) {
1115
+ if (err instanceof Error && "code" in err && err.code === "ENOENT") {
1116
+ return void 0;
1117
+ }
1118
+ process.stderr.write(
1119
+ `[neuroverse] Warning: Failed to read ${filename}: ${err instanceof Error ? err.message : String(err)}
1120
+ `
1121
+ );
994
1122
  return void 0;
995
1123
  }
996
1124
  }
@@ -1012,10 +1140,23 @@ async function loadWorldFromDirectory(dirPath) {
1012
1140
  const rulesDir = join(dirPath, "rules");
1013
1141
  const ruleFiles = readdirSync(rulesDir).filter((f) => f.endsWith(".json")).sort();
1014
1142
  for (const file of ruleFiles) {
1015
- const content = await readFile(join(rulesDir, file), "utf-8");
1016
- rules.push(JSON.parse(content));
1143
+ try {
1144
+ const content = await readFile(join(rulesDir, file), "utf-8");
1145
+ rules.push(JSON.parse(content));
1146
+ } catch (err) {
1147
+ process.stderr.write(
1148
+ `[neuroverse] Warning: Failed to parse rule ${file}: ${err instanceof Error ? err.message : String(err)}
1149
+ `
1150
+ );
1151
+ }
1152
+ }
1153
+ } catch (err) {
1154
+ if (!(err instanceof Error && "code" in err && err.code === "ENOENT")) {
1155
+ process.stderr.write(
1156
+ `[neuroverse] Warning: Failed to read rules directory: ${err instanceof Error ? err.message : String(err)}
1157
+ `
1158
+ );
1017
1159
  }
1018
- } catch {
1019
1160
  }
1020
1161
  return {
1021
1162
  world: worldJson,
@@ -1050,20 +1191,55 @@ async function loadWorld(worldPath) {
1050
1191
  if (info.isDirectory()) {
1051
1192
  return loadWorldFromDirectory(worldPath);
1052
1193
  }
1053
- if (worldPath.endsWith(".nv-world.zip")) {
1054
- throw new Error(".nv-world.zip loading not yet implemented \u2014 use a world directory");
1055
- }
1056
- throw new Error(`Cannot load world from: ${worldPath} \u2014 expected a directory or .nv-world.zip`);
1194
+ throw new Error(`Cannot load world from: ${worldPath} \u2014 expected a directory`);
1057
1195
  }
1058
1196
 
1059
- // src/adapters/openclaw.ts
1197
+ // src/adapters/shared.ts
1060
1198
  var GovernanceBlockedError = class extends Error {
1061
1199
  verdict;
1062
- action;
1063
- constructor(verdict, action) {
1064
- super(`[NeuroVerse] BLOCKED: ${verdict.reason ?? verdict.ruleId ?? "governance rule"}`);
1200
+ constructor(verdict, message) {
1201
+ super(message ?? `[NeuroVerse] BLOCKED: ${verdict.reason ?? verdict.ruleId ?? "governance rule"}`);
1065
1202
  this.name = "GovernanceBlockedError";
1066
1203
  this.verdict = verdict;
1204
+ }
1205
+ };
1206
+ function trackPlanProgress(event, state, callbacks) {
1207
+ if (!state.activePlan) return;
1208
+ const planVerdict = evaluatePlan(event, state.activePlan);
1209
+ if (planVerdict.matchedStep) {
1210
+ const advResult = advancePlan(state.activePlan, planVerdict.matchedStep);
1211
+ if (advResult.success && advResult.plan) {
1212
+ state.activePlan = advResult.plan;
1213
+ state.engineOptions.plan = state.activePlan;
1214
+ }
1215
+ const progress = getPlanProgress(state.activePlan);
1216
+ callbacks.onPlanProgress?.(progress);
1217
+ if (progress.completed === progress.total) {
1218
+ callbacks.onPlanComplete?.();
1219
+ }
1220
+ }
1221
+ }
1222
+ function extractScope(args) {
1223
+ if (typeof args.path === "string") return args.path;
1224
+ if (typeof args.file_path === "string") return args.file_path;
1225
+ if (typeof args.filename === "string") return args.filename;
1226
+ if (typeof args.url === "string") return args.url;
1227
+ if (typeof args.command === "string") return args.command;
1228
+ return void 0;
1229
+ }
1230
+ function buildEngineOptions(options, plan) {
1231
+ return {
1232
+ trace: options.trace ?? false,
1233
+ level: options.level,
1234
+ plan: plan ?? options.plan
1235
+ };
1236
+ }
1237
+
1238
+ // src/adapters/openclaw.ts
1239
+ var GovernanceBlockedError2 = class extends GovernanceBlockedError {
1240
+ action;
1241
+ constructor(verdict, action) {
1242
+ super(verdict);
1067
1243
  this.action = action;
1068
1244
  }
1069
1245
  };
@@ -1073,7 +1249,7 @@ function defaultMapAction(action, direction) {
1073
1249
  tool: action.tool ?? action.type,
1074
1250
  args: action.input,
1075
1251
  direction,
1076
- scope: typeof action.input?.path === "string" ? action.input.path : typeof action.input?.url === "string" ? action.input.url : void 0
1252
+ scope: action.input ? extractScope(action.input) : void 0
1077
1253
  };
1078
1254
  }
1079
1255
  var NeuroVersePlugin = class {
@@ -1087,11 +1263,7 @@ var NeuroVersePlugin = class {
1087
1263
  this.world = world;
1088
1264
  this.options = options;
1089
1265
  this.activePlan = options.plan;
1090
- this.engineOptions = {
1091
- trace: options.trace ?? false,
1092
- level: options.level,
1093
- plan: this.activePlan
1094
- };
1266
+ this.engineOptions = buildEngineOptions(options, this.activePlan);
1095
1267
  this.mapAction = options.mapAction ?? defaultMapAction;
1096
1268
  }
1097
1269
  /**
@@ -1111,22 +1283,10 @@ var NeuroVersePlugin = class {
1111
1283
  };
1112
1284
  this.options.onEvaluate?.(result);
1113
1285
  if (verdict.status === "BLOCK") {
1114
- throw new GovernanceBlockedError(verdict, action);
1286
+ throw new GovernanceBlockedError2(verdict, action);
1115
1287
  }
1116
- if (verdict.status === "ALLOW" && this.activePlan) {
1117
- const planVerdict = evaluatePlan(event, this.activePlan);
1118
- if (planVerdict.matchedStep) {
1119
- const advResult = advancePlan(this.activePlan, planVerdict.matchedStep);
1120
- if (advResult.success && advResult.plan) {
1121
- this.activePlan = advResult.plan;
1122
- this.engineOptions.plan = this.activePlan;
1123
- }
1124
- const progress = getPlanProgress(this.activePlan);
1125
- this.options.onPlanProgress?.(progress);
1126
- if (progress.completed === progress.total) {
1127
- this.options.onPlanComplete?.();
1128
- }
1129
- }
1288
+ if (verdict.status === "ALLOW") {
1289
+ trackPlanProgress(event, this, this.options);
1130
1290
  }
1131
1291
  return result;
1132
1292
  }
@@ -1147,7 +1307,7 @@ var NeuroVersePlugin = class {
1147
1307
  };
1148
1308
  this.options.onEvaluate?.(result);
1149
1309
  if (verdict.status === "BLOCK") {
1150
- throw new GovernanceBlockedError(verdict, action);
1310
+ throw new GovernanceBlockedError2(verdict, action);
1151
1311
  }
1152
1312
  return result;
1153
1313
  }
@@ -1,4 +1,5 @@
1
- import { a as GuardVerdict, W as WorldDefinition, G as GuardEvent, P as PlanDefinition, b as PlanProgress } from '../guard-contract-WZx__PmU.cjs';
1
+ import { a as GuardVerdict, b as GuardEngineOptions, P as PlanDefinition, W as WorldDefinition, G as GuardEvent, c as PlanProgress } from '../guard-contract-DqFcTScd.cjs';
2
+ import { G as GovernanceBlockedError$1 } from '../shared-B8dvUUD8.cjs';
2
3
 
3
4
  /**
4
5
  * NeuroVerse Adapter — OpenClaw
@@ -45,8 +46,7 @@ interface NeuroVersePluginOptions {
45
46
  /** Called when all plan steps are completed. */
46
47
  onPlanComplete?: () => void;
47
48
  }
48
- declare class GovernanceBlockedError extends Error {
49
- readonly verdict: GuardVerdict;
49
+ declare class GovernanceBlockedError extends GovernanceBlockedError$1 {
50
50
  readonly action: AgentAction;
51
51
  constructor(verdict: GuardVerdict, action: AgentAction);
52
52
  }
@@ -61,9 +61,9 @@ declare class NeuroVersePlugin {
61
61
  readonly name = "neuroverse-governance";
62
62
  private world;
63
63
  private options;
64
- private engineOptions;
64
+ engineOptions: GuardEngineOptions;
65
65
  private mapAction;
66
- private activePlan?;
66
+ activePlan?: PlanDefinition;
67
67
  constructor(world: WorldDefinition, options?: NeuroVersePluginOptions);
68
68
  /**
69
69
  * Evaluate an action before execution.
@@ -84,7 +84,7 @@ declare class NeuroVersePlugin {
84
84
  */
85
85
  hooks(): {
86
86
  beforeAction: (action: AgentAction) => HookResult;
87
- afterAction: (action: AgentAction, output?: unknown) => HookResult;
87
+ afterAction: (action: AgentAction, output?: unknown) => HookResult | null;
88
88
  };
89
89
  }
90
90
  /**
@@ -1,4 +1,5 @@
1
- import { a as GuardVerdict, W as WorldDefinition, G as GuardEvent, P as PlanDefinition, b as PlanProgress } from '../guard-contract-WZx__PmU.js';
1
+ import { a as GuardVerdict, b as GuardEngineOptions, P as PlanDefinition, W as WorldDefinition, G as GuardEvent, c as PlanProgress } from '../guard-contract-DqFcTScd.js';
2
+ import { G as GovernanceBlockedError$1 } from '../shared-Dr5Wiay8.js';
2
3
 
3
4
  /**
4
5
  * NeuroVerse Adapter — OpenClaw
@@ -45,8 +46,7 @@ interface NeuroVersePluginOptions {
45
46
  /** Called when all plan steps are completed. */
46
47
  onPlanComplete?: () => void;
47
48
  }
48
- declare class GovernanceBlockedError extends Error {
49
- readonly verdict: GuardVerdict;
49
+ declare class GovernanceBlockedError extends GovernanceBlockedError$1 {
50
50
  readonly action: AgentAction;
51
51
  constructor(verdict: GuardVerdict, action: AgentAction);
52
52
  }
@@ -61,9 +61,9 @@ declare class NeuroVersePlugin {
61
61
  readonly name = "neuroverse-governance";
62
62
  private world;
63
63
  private options;
64
- private engineOptions;
64
+ engineOptions: GuardEngineOptions;
65
65
  private mapAction;
66
- private activePlan?;
66
+ activePlan?: PlanDefinition;
67
67
  constructor(world: WorldDefinition, options?: NeuroVersePluginOptions);
68
68
  /**
69
69
  * Evaluate an action before execution.
@@ -84,7 +84,7 @@ declare class NeuroVersePlugin {
84
84
  */
85
85
  hooks(): {
86
86
  beforeAction: (action: AgentAction) => HookResult;
87
- afterAction: (action: AgentAction, output?: unknown) => HookResult;
87
+ afterAction: (action: AgentAction, output?: unknown) => HookResult | null;
88
88
  };
89
89
  }
90
90
  /**
@@ -3,11 +3,12 @@ import {
3
3
  NeuroVersePlugin,
4
4
  createNeuroVersePlugin,
5
5
  createNeuroVersePluginFromWorld
6
- } from "../chunk-2PQU3VAN.js";
7
- import "../chunk-4JRYGIO7.js";
8
- import "../chunk-4QXB6PEO.js";
9
- import "../chunk-JZPQGIKR.js";
10
- import "../chunk-YZFATT7X.js";
6
+ } from "../chunk-BNKJPUPQ.js";
7
+ import "../chunk-5U2MQO5P.js";
8
+ import "../chunk-W7LLXRGY.js";
9
+ import "../chunk-QLPTHTVB.js";
10
+ import "../chunk-CTZHONLA.js";
11
+ import "../chunk-QWGCMQQD.js";
11
12
  export {
12
13
  GovernanceBlockedError,
13
14
  NeuroVersePlugin,