@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.
- package/.well-known/ai-plugin.json +34 -9
- package/AGENTS.md +72 -24
- package/README.md +352 -237
- package/dist/adapters/autoresearch.cjs +1152 -3
- package/dist/adapters/autoresearch.d.cts +11 -3
- package/dist/adapters/autoresearch.d.ts +11 -3
- package/dist/adapters/autoresearch.js +9 -4
- package/dist/adapters/deep-agents.cjs +1528 -0
- package/dist/adapters/deep-agents.d.cts +181 -0
- package/dist/adapters/deep-agents.d.ts +181 -0
- package/dist/adapters/deep-agents.js +17 -0
- package/dist/adapters/express.cjs +171 -32
- package/dist/adapters/express.d.cts +1 -1
- package/dist/adapters/express.d.ts +1 -1
- package/dist/adapters/express.js +5 -5
- package/dist/adapters/index.cjs +564 -121
- package/dist/adapters/index.d.cts +3 -1
- package/dist/adapters/index.d.ts +3 -1
- package/dist/adapters/index.js +38 -16
- package/dist/adapters/langchain.cjs +217 -57
- package/dist/adapters/langchain.d.cts +5 -5
- package/dist/adapters/langchain.d.ts +5 -5
- package/dist/adapters/langchain.js +6 -5
- package/dist/adapters/openai.cjs +219 -59
- package/dist/adapters/openai.d.cts +5 -5
- package/dist/adapters/openai.d.ts +5 -5
- package/dist/adapters/openai.js +6 -5
- package/dist/adapters/openclaw.cjs +217 -57
- package/dist/adapters/openclaw.d.cts +6 -6
- package/dist/adapters/openclaw.d.ts +6 -6
- package/dist/adapters/openclaw.js +6 -5
- package/dist/add-ROOZLU62.js +314 -0
- package/dist/behavioral-MJO34S6Q.js +118 -0
- package/dist/{bootstrap-GXVDZNF7.js → bootstrap-CQRZVOXK.js} +6 -4
- package/dist/bootstrap-emitter-Q7UIJZ2O.js +7 -0
- package/dist/bootstrap-parser-EEF36XDU.js +7 -0
- package/dist/browser.global.js +941 -0
- package/dist/{build-P42YFKQV.js → build-QKOBBC23.js} +7 -5
- package/dist/{chunk-COT5XS4V.js → chunk-3WQLXYTP.js} +17 -35
- package/dist/{chunk-ER62HNGF.js → chunk-4FLICVVA.js} +17 -37
- package/dist/chunk-5TPFNWRU.js +215 -0
- package/dist/chunk-5U2MQO5P.js +57 -0
- package/dist/{chunk-NF5POFCI.js → chunk-6S5CFQXY.js} +6 -4
- package/dist/{chunk-QPASI2BR.js → chunk-A7GKPPU7.js} +49 -10
- package/dist/{chunk-OGL7QXZS.js → chunk-B6OXJLJ5.js} +17 -3
- package/dist/{chunk-2PQU3VAN.js → chunk-BNKJPUPQ.js} +17 -35
- package/dist/chunk-BQZMOEML.js +43 -0
- package/dist/chunk-CNSO6XW5.js +207 -0
- package/dist/{chunk-JZPQGIKR.js → chunk-CTZHONLA.js} +65 -9
- package/dist/chunk-D2UCV5AK.js +326 -0
- package/dist/{chunk-XPDMYECO.js → chunk-EMQDLDAF.js} +1 -185
- package/dist/{chunk-GR6DGCZ2.js → chunk-F66BVUYB.js} +3 -3
- package/dist/{chunk-2NICNKOM.js → chunk-G7DJ6VOD.js} +5 -4
- package/dist/{chunk-4A7LISES.js → chunk-IS4WUH6Y.js} +45 -6
- package/dist/{chunk-MWDQ4MJB.js → chunk-MH7BT4VH.js} +5 -1
- package/dist/chunk-O5ABKEA7.js +304 -0
- package/dist/chunk-PVTQQS3Y.js +186 -0
- package/dist/{chunk-4QXB6PEO.js → chunk-QLPTHTVB.js} +37 -16
- package/dist/chunk-QWGCMQQD.js +16 -0
- package/dist/{chunk-T5EUJQE5.js → chunk-QXBFT7NI.js} +31 -2
- package/dist/{chunk-PDOZHZWL.js → chunk-TG6SEF24.js} +25 -4
- package/dist/chunk-U6U7EJZL.js +177 -0
- package/dist/{chunk-4JRYGIO7.js → chunk-W7LLXRGY.js} +110 -7
- package/dist/{chunk-BUWWN2NX.js → chunk-ZJTDUCC2.js} +9 -7
- package/dist/{chunk-FYS2CBUW.js → chunk-ZWI3NIXK.js} +10 -0
- package/dist/cli/neuroverse.cjs +5091 -2348
- package/dist/cli/neuroverse.js +52 -21
- package/dist/cli/plan.cjs +881 -41
- package/dist/cli/plan.js +7 -15
- package/dist/cli/run.cjs +289 -34
- package/dist/cli/run.js +4 -4
- package/dist/{configure-ai-TK67ZWZL.js → configure-ai-6TZ3MCSI.js} +1 -1
- package/dist/decision-flow-M63D47LO.js +61 -0
- package/dist/demo-G43RLCPK.js +469 -0
- package/dist/{derive-TLIV4OOU.js → derive-FJZVIPUZ.js} +5 -4
- package/dist/{doctor-XPDLEYXN.js → doctor-6BC6X2VO.js} +6 -4
- package/dist/equity-penalties-SG5IZQ7I.js +244 -0
- package/dist/{explain-IDCRWMPX.js → explain-RHBU2GBR.js} +6 -25
- package/dist/{guard-RV65TT4L.js → guard-AJCCGZMF.js} +8 -12
- package/dist/{guard-contract-WZx__PmU.d.cts → guard-contract-DqFcTScd.d.cts} +117 -5
- package/dist/{guard-contract-WZx__PmU.d.ts → guard-contract-DqFcTScd.d.ts} +117 -5
- package/dist/{guard-engine-JLTUARGU.js → guard-engine-PNR6MHCM.js} +3 -3
- package/dist/{impact-XPECYRLH.js → impact-3XVDSCBU.js} +5 -5
- package/dist/{improve-GPUBKTEA.js → improve-TQP4ECSY.js} +7 -26
- package/dist/index.cjs +5597 -4279
- package/dist/index.d.cts +597 -18
- package/dist/index.d.ts +597 -18
- package/dist/index.js +134 -41
- package/dist/{infer-world-7GVZWFX4.js → infer-world-IFXCACJ5.js} +1 -1
- package/dist/{init-PKPIYHYE.js → init-FYPV4SST.js} +1 -1
- package/dist/{init-world-VWMQZQC7.js → init-world-TI7ARHBT.js} +1 -1
- package/dist/mcp-server-5Y3ZM7TV.js +13 -0
- package/dist/{model-adapter-BB7G4MFI.js → model-adapter-VXEKB4LS.js} +1 -1
- package/dist/{playground-E664U4T6.js → playground-VZBNPPBO.js} +29 -19
- package/dist/{redteam-Z7WREJ44.js → redteam-MZPZD3EF.js} +4 -4
- package/dist/session-JYOARW54.js +15 -0
- package/dist/shared-7RLUHNMU.js +16 -0
- package/dist/shared-B8dvUUD8.d.cts +60 -0
- package/dist/shared-Dr5Wiay8.d.ts +60 -0
- package/dist/{simulate-VDOYQFRO.js → simulate-LJXYBC6M.js} +8 -33
- package/dist/{test-OGXJK4QU.js → test-BOOR4A5F.js} +4 -4
- package/dist/{trace-JVF67VR3.js → trace-PKV4KX56.js} +4 -4
- package/dist/{validate-LLBWVPGV.js → validate-RALX7CZS.js} +2 -2
- package/dist/{validate-engine-UIABSIHD.js → validate-engine-7ZXFVGF2.js} +1 -1
- package/dist/viz/assets/index-B8SaeJZZ.js +23 -0
- package/dist/viz/index.html +23 -0
- package/dist/{world-LAXO6DOX.js → world-BIP4GZBZ.js} +9 -11
- package/dist/world-loader-Y6HMQH2D.js +13 -0
- package/dist/worlds/coding-agent.nv-world.md +211 -0
- package/dist/worlds/research-agent.nv-world.md +169 -0
- package/dist/worlds/social-media.nv-world.md +198 -0
- package/dist/worlds/trading-agent.nv-world.md +218 -0
- package/examples/social-media-sim/bridge.py +209 -0
- package/examples/social-media-sim/simulation.py +927 -0
- package/package.json +30 -4
- package/policies/content-moderation-rules.txt +8 -0
- package/policies/marketing-rules.txt +8 -0
- package/policies/science-research-rules.txt +11 -0
- package/policies/social-media-rules.txt +7 -0
- package/policies/strict-rules.txt +8 -0
- package/policies/trading-rules.txt +8 -0
- package/simulate.html +1567 -0
- package/dist/chunk-YZFATT7X.js +0 -9
- package/dist/mcp-server-FPVSU32Z.js +0 -13
- package/dist/session-EKTRSR7C.js +0 -14
- 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: () =>
|
|
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/
|
|
41
|
-
function
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
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
|
-
|
|
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 *
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
1016
|
-
|
|
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
|
-
|
|
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/
|
|
1197
|
+
// src/adapters/shared.ts
|
|
1060
1198
|
var GovernanceBlockedError = class extends Error {
|
|
1061
1199
|
verdict;
|
|
1062
|
-
|
|
1063
|
-
|
|
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:
|
|
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
|
|
1286
|
+
throw new GovernanceBlockedError2(verdict, action);
|
|
1115
1287
|
}
|
|
1116
|
-
if (verdict.status === "ALLOW"
|
|
1117
|
-
|
|
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
|
|
1310
|
+
throw new GovernanceBlockedError2(verdict, action);
|
|
1151
1311
|
}
|
|
1152
1312
|
return result;
|
|
1153
1313
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { a as GuardVerdict,
|
|
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
|
|
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
|
-
|
|
64
|
+
engineOptions: GuardEngineOptions;
|
|
65
65
|
private mapAction;
|
|
66
|
-
|
|
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,
|
|
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
|
|
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
|
-
|
|
64
|
+
engineOptions: GuardEngineOptions;
|
|
65
65
|
private mapAction;
|
|
66
|
-
|
|
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-
|
|
7
|
-
import "../chunk-
|
|
8
|
-
import "../chunk-
|
|
9
|
-
import "../chunk-
|
|
10
|
-
import "../chunk-
|
|
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,
|