@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
|
@@ -2,17 +2,19 @@ import {
|
|
|
2
2
|
DeriveInputError,
|
|
3
3
|
DeriveProviderError,
|
|
4
4
|
deriveWorld
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-6S5CFQXY.js";
|
|
6
6
|
import {
|
|
7
7
|
DERIVE_EXIT_CODES
|
|
8
8
|
} from "./chunk-Q6O7ZLO2.js";
|
|
9
9
|
import "./chunk-OT6PXH54.js";
|
|
10
|
+
import "./chunk-7P3S7MAY.js";
|
|
10
11
|
import {
|
|
11
|
-
emitWorldDefinition,
|
|
12
12
|
parseWorldMarkdown
|
|
13
|
-
} from "./chunk-
|
|
14
|
-
import
|
|
15
|
-
|
|
13
|
+
} from "./chunk-EMQDLDAF.js";
|
|
14
|
+
import {
|
|
15
|
+
emitWorldDefinition
|
|
16
|
+
} from "./chunk-PVTQQS3Y.js";
|
|
17
|
+
import "./chunk-QWGCMQQD.js";
|
|
16
18
|
|
|
17
19
|
// src/cli/build.ts
|
|
18
20
|
var FINDING_LABELS = {
|
|
@@ -1,23 +1,21 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
GovernanceBlockedError,
|
|
3
|
+
buildEngineOptions,
|
|
4
|
+
extractScope,
|
|
5
|
+
trackPlanProgress
|
|
6
|
+
} from "./chunk-5U2MQO5P.js";
|
|
4
7
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
getPlanProgress
|
|
8
|
-
} from "./chunk-4QXB6PEO.js";
|
|
8
|
+
evaluateGuard
|
|
9
|
+
} from "./chunk-W7LLXRGY.js";
|
|
9
10
|
import {
|
|
10
11
|
loadWorld
|
|
11
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-CTZHONLA.js";
|
|
12
13
|
|
|
13
14
|
// src/adapters/langchain.ts
|
|
14
|
-
var
|
|
15
|
-
verdict;
|
|
15
|
+
var GovernanceBlockedError2 = class extends GovernanceBlockedError {
|
|
16
16
|
event;
|
|
17
17
|
constructor(verdict, event) {
|
|
18
|
-
super(
|
|
19
|
-
this.name = "GovernanceBlockedError";
|
|
20
|
-
this.verdict = verdict;
|
|
18
|
+
super(verdict);
|
|
21
19
|
this.event = event;
|
|
22
20
|
}
|
|
23
21
|
};
|
|
@@ -25,7 +23,7 @@ function defaultMapToolCall(toolName, toolInput) {
|
|
|
25
23
|
return {
|
|
26
24
|
intent: toolName,
|
|
27
25
|
tool: toolName,
|
|
28
|
-
scope:
|
|
26
|
+
scope: extractScope(toolInput),
|
|
29
27
|
args: toolInput,
|
|
30
28
|
direction: "input"
|
|
31
29
|
};
|
|
@@ -41,11 +39,7 @@ var NeuroVerseCallbackHandler = class {
|
|
|
41
39
|
this.world = world;
|
|
42
40
|
this.options = options;
|
|
43
41
|
this.activePlan = options.plan;
|
|
44
|
-
this.engineOptions =
|
|
45
|
-
trace: options.trace ?? false,
|
|
46
|
-
level: options.level,
|
|
47
|
-
plan: this.activePlan
|
|
48
|
-
};
|
|
42
|
+
this.engineOptions = buildEngineOptions(options, this.activePlan);
|
|
49
43
|
this.mapToolCall = options.mapToolCall ?? defaultMapToolCall;
|
|
50
44
|
}
|
|
51
45
|
/**
|
|
@@ -68,28 +62,16 @@ var NeuroVerseCallbackHandler = class {
|
|
|
68
62
|
this.options.onEvaluate?.(verdict, event);
|
|
69
63
|
if (verdict.status === "BLOCK") {
|
|
70
64
|
this.options.onBlock?.(verdict, event);
|
|
71
|
-
throw new
|
|
65
|
+
throw new GovernanceBlockedError2(verdict, event);
|
|
72
66
|
}
|
|
73
67
|
if (verdict.status === "PAUSE") {
|
|
74
68
|
const approved = await this.options.onPause?.(verdict, event);
|
|
75
69
|
if (!approved) {
|
|
76
|
-
throw new
|
|
70
|
+
throw new GovernanceBlockedError2(verdict, event);
|
|
77
71
|
}
|
|
78
72
|
}
|
|
79
|
-
if (verdict.status === "ALLOW"
|
|
80
|
-
|
|
81
|
-
if (planVerdict.matchedStep) {
|
|
82
|
-
const advResult = advancePlan(this.activePlan, planVerdict.matchedStep);
|
|
83
|
-
if (advResult.success && advResult.plan) {
|
|
84
|
-
this.activePlan = advResult.plan;
|
|
85
|
-
this.engineOptions.plan = this.activePlan;
|
|
86
|
-
}
|
|
87
|
-
const progress = getPlanProgress(this.activePlan);
|
|
88
|
-
this.options.onPlanProgress?.(progress);
|
|
89
|
-
if (progress.completed === progress.total) {
|
|
90
|
-
this.options.onPlanComplete?.();
|
|
91
|
-
}
|
|
92
|
-
}
|
|
73
|
+
if (verdict.status === "ALLOW") {
|
|
74
|
+
trackPlanProgress(event, this, this.options);
|
|
93
75
|
}
|
|
94
76
|
}
|
|
95
77
|
};
|
|
@@ -102,7 +84,7 @@ function createNeuroVerseCallbackHandlerFromWorld(world, options) {
|
|
|
102
84
|
}
|
|
103
85
|
|
|
104
86
|
export {
|
|
105
|
-
GovernanceBlockedError,
|
|
87
|
+
GovernanceBlockedError2 as GovernanceBlockedError,
|
|
106
88
|
NeuroVerseCallbackHandler,
|
|
107
89
|
createNeuroVerseCallbackHandler,
|
|
108
90
|
createNeuroVerseCallbackHandlerFromWorld
|
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
GovernanceBlockedError,
|
|
3
|
+
buildEngineOptions,
|
|
4
|
+
defaultBlockMessage,
|
|
5
|
+
extractScope,
|
|
6
|
+
trackPlanProgress
|
|
7
|
+
} from "./chunk-5U2MQO5P.js";
|
|
4
8
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
getPlanProgress
|
|
8
|
-
} from "./chunk-4QXB6PEO.js";
|
|
9
|
+
evaluateGuard
|
|
10
|
+
} from "./chunk-W7LLXRGY.js";
|
|
9
11
|
import {
|
|
10
12
|
loadWorld
|
|
11
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-CTZHONLA.js";
|
|
12
14
|
|
|
13
15
|
// src/adapters/openai.ts
|
|
14
|
-
var
|
|
15
|
-
verdict;
|
|
16
|
+
var GovernanceBlockedError2 = class extends GovernanceBlockedError {
|
|
16
17
|
toolCallId;
|
|
17
18
|
constructor(verdict, toolCallId) {
|
|
18
|
-
super(
|
|
19
|
-
this.name = "GovernanceBlockedError";
|
|
20
|
-
this.verdict = verdict;
|
|
19
|
+
super(verdict);
|
|
21
20
|
this.toolCallId = toolCallId;
|
|
22
21
|
}
|
|
23
22
|
};
|
|
@@ -25,14 +24,11 @@ function defaultMapFunctionCall(name, args) {
|
|
|
25
24
|
return {
|
|
26
25
|
intent: name,
|
|
27
26
|
tool: name,
|
|
28
|
-
scope:
|
|
27
|
+
scope: extractScope(args),
|
|
29
28
|
args,
|
|
30
29
|
direction: "input"
|
|
31
30
|
};
|
|
32
31
|
}
|
|
33
|
-
function defaultBlockMessage(verdict) {
|
|
34
|
-
return `Action blocked by governance policy: ${verdict.reason ?? "rule violation"}. Rule: ${verdict.ruleId ?? "unknown"}.`;
|
|
35
|
-
}
|
|
36
32
|
var GovernedToolExecutor = class {
|
|
37
33
|
world;
|
|
38
34
|
options;
|
|
@@ -44,11 +40,7 @@ var GovernedToolExecutor = class {
|
|
|
44
40
|
this.world = world;
|
|
45
41
|
this.options = options;
|
|
46
42
|
this.activePlan = options.plan;
|
|
47
|
-
this.engineOptions =
|
|
48
|
-
trace: options.trace ?? false,
|
|
49
|
-
level: options.level,
|
|
50
|
-
plan: this.activePlan
|
|
51
|
-
};
|
|
43
|
+
this.engineOptions = buildEngineOptions(options, this.activePlan);
|
|
52
44
|
this.mapFn = options.mapFunctionCall ?? defaultMapFunctionCall;
|
|
53
45
|
this.blockMsg = options.blockMessage ?? defaultBlockMessage;
|
|
54
46
|
}
|
|
@@ -67,20 +59,8 @@ var GovernedToolExecutor = class {
|
|
|
67
59
|
this.engineOptions.plan = this.activePlan;
|
|
68
60
|
const verdict = evaluateGuard(event, this.world, this.engineOptions);
|
|
69
61
|
this.options.onEvaluate?.(verdict, event);
|
|
70
|
-
if (verdict.status === "ALLOW"
|
|
71
|
-
|
|
72
|
-
if (planVerdict.matchedStep) {
|
|
73
|
-
const advResult = advancePlan(this.activePlan, planVerdict.matchedStep);
|
|
74
|
-
if (advResult.success && advResult.plan) {
|
|
75
|
-
this.activePlan = advResult.plan;
|
|
76
|
-
this.engineOptions.plan = this.activePlan;
|
|
77
|
-
}
|
|
78
|
-
const progress = getPlanProgress(this.activePlan);
|
|
79
|
-
this.options.onPlanProgress?.(progress);
|
|
80
|
-
if (progress.completed === progress.total) {
|
|
81
|
-
this.options.onPlanComplete?.();
|
|
82
|
-
}
|
|
83
|
-
}
|
|
62
|
+
if (verdict.status === "ALLOW") {
|
|
63
|
+
trackPlanProgress(event, this, this.options);
|
|
84
64
|
}
|
|
85
65
|
return verdict;
|
|
86
66
|
}
|
|
@@ -106,7 +86,7 @@ var GovernedToolExecutor = class {
|
|
|
106
86
|
};
|
|
107
87
|
}
|
|
108
88
|
if (verdict.status === "PAUSE") {
|
|
109
|
-
throw new
|
|
89
|
+
throw new GovernanceBlockedError2(verdict, toolCall.id);
|
|
110
90
|
}
|
|
111
91
|
let args;
|
|
112
92
|
try {
|
|
@@ -132,7 +112,7 @@ function createGovernedToolExecutorFromWorld(world, options) {
|
|
|
132
112
|
}
|
|
133
113
|
|
|
134
114
|
export {
|
|
135
|
-
GovernanceBlockedError,
|
|
115
|
+
GovernanceBlockedError2 as GovernanceBlockedError,
|
|
136
116
|
GovernedToolExecutor,
|
|
137
117
|
createGovernedToolExecutor,
|
|
138
118
|
createGovernedToolExecutorFromWorld
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import {
|
|
2
|
+
validateWorld
|
|
3
|
+
} from "./chunk-7P3S7MAY.js";
|
|
4
|
+
|
|
5
|
+
// src/engine/add-engine.ts
|
|
6
|
+
function slugify(text) {
|
|
7
|
+
return text.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, "").slice(0, 60);
|
|
8
|
+
}
|
|
9
|
+
async function addGuard(worldDir, input) {
|
|
10
|
+
const { readFile, writeFile } = await import("fs/promises");
|
|
11
|
+
const { join } = await import("path");
|
|
12
|
+
const guardsPath = join(worldDir, "guards.json");
|
|
13
|
+
let config;
|
|
14
|
+
try {
|
|
15
|
+
const raw = await readFile(guardsPath, "utf-8");
|
|
16
|
+
config = JSON.parse(raw);
|
|
17
|
+
} catch {
|
|
18
|
+
config = { guards: [], intent_vocabulary: {} };
|
|
19
|
+
}
|
|
20
|
+
const id = input.id ?? `guard_${slugify(input.label)}`;
|
|
21
|
+
if (config.guards.some((g) => g.id === id)) {
|
|
22
|
+
throw new Error(`Guard with id "${id}" already exists. Use a different label or provide --id.`);
|
|
23
|
+
}
|
|
24
|
+
const guard = {
|
|
25
|
+
id,
|
|
26
|
+
label: input.label,
|
|
27
|
+
description: input.description ?? input.label,
|
|
28
|
+
category: input.category ?? "operational",
|
|
29
|
+
enforcement: input.enforcement,
|
|
30
|
+
immutable: false,
|
|
31
|
+
intent_patterns: input.intentPatterns,
|
|
32
|
+
...input.appliesTo && { appliesTo: input.appliesTo },
|
|
33
|
+
...input.invariantRef && { invariant_ref: input.invariantRef },
|
|
34
|
+
...input.enforcement === "modify" && input.reason && { modify_to: input.reason }
|
|
35
|
+
};
|
|
36
|
+
config.guards.push(guard);
|
|
37
|
+
await writeFile(guardsPath, JSON.stringify(config, null, 2) + "\n");
|
|
38
|
+
const { loadWorldFromDirectory } = await import("./world-loader-Y6HMQH2D.js");
|
|
39
|
+
const world = await loadWorldFromDirectory(worldDir);
|
|
40
|
+
const report = validateWorld(world);
|
|
41
|
+
return {
|
|
42
|
+
type: "guard",
|
|
43
|
+
id,
|
|
44
|
+
file: guardsPath,
|
|
45
|
+
valid: report.summary.isHealthy,
|
|
46
|
+
findings: report.findings,
|
|
47
|
+
construct: guard
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
async function addRule(worldDir, input) {
|
|
51
|
+
const { readFile, writeFile, mkdir } = await import("fs/promises");
|
|
52
|
+
const { join } = await import("path");
|
|
53
|
+
const { readdirSync } = await import("fs");
|
|
54
|
+
const rulesDir = join(worldDir, "rules");
|
|
55
|
+
await mkdir(rulesDir, { recursive: true });
|
|
56
|
+
let nextNum = 1;
|
|
57
|
+
try {
|
|
58
|
+
const existing = readdirSync(rulesDir).filter((f) => f.match(/^rule-\d+\.json$/)).sort();
|
|
59
|
+
if (existing.length > 0) {
|
|
60
|
+
const lastFile = existing[existing.length - 1];
|
|
61
|
+
const match = lastFile.match(/rule-(\d+)\.json/);
|
|
62
|
+
if (match) nextNum = parseInt(match[1], 10) + 1;
|
|
63
|
+
}
|
|
64
|
+
} catch {
|
|
65
|
+
}
|
|
66
|
+
const ruleNum = String(nextNum).padStart(3, "0");
|
|
67
|
+
const id = input.id ?? `rule_${slugify(input.label)}`;
|
|
68
|
+
const rule = {
|
|
69
|
+
id,
|
|
70
|
+
severity: input.severity,
|
|
71
|
+
label: input.label,
|
|
72
|
+
description: input.description ?? input.label,
|
|
73
|
+
order: nextNum,
|
|
74
|
+
triggers: input.triggers,
|
|
75
|
+
...input.effects && { effects: input.effects },
|
|
76
|
+
...input.collapseCheck && { collapse_check: input.collapseCheck },
|
|
77
|
+
causal_translation: input.causalTranslation ?? {
|
|
78
|
+
trigger_text: `Triggers when: ${input.triggers.map((t) => `${t.field} ${t.operator} ${t.value}`).join(" AND ")}`,
|
|
79
|
+
rule_text: input.label,
|
|
80
|
+
shift_text: input.description ?? input.label,
|
|
81
|
+
effect_text: input.effects ? input.effects.map((e) => `${e.target} ${e.operation} ${e.value}`).join(", ") : "No direct effects"
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
const rulePath = join(rulesDir, `rule-${ruleNum}.json`);
|
|
85
|
+
await writeFile(rulePath, JSON.stringify(rule, null, 2) + "\n");
|
|
86
|
+
const { loadWorldFromDirectory } = await import("./world-loader-Y6HMQH2D.js");
|
|
87
|
+
const world = await loadWorldFromDirectory(worldDir);
|
|
88
|
+
const report = validateWorld(world);
|
|
89
|
+
return {
|
|
90
|
+
type: "rule",
|
|
91
|
+
id,
|
|
92
|
+
file: rulePath,
|
|
93
|
+
valid: report.summary.isHealthy,
|
|
94
|
+
findings: report.findings,
|
|
95
|
+
construct: rule
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
async function addInvariant(worldDir, input) {
|
|
99
|
+
const { readFile, writeFile } = await import("fs/promises");
|
|
100
|
+
const { join } = await import("path");
|
|
101
|
+
const invariantsPath = join(worldDir, "invariants.json");
|
|
102
|
+
let config;
|
|
103
|
+
try {
|
|
104
|
+
const raw = await readFile(invariantsPath, "utf-8");
|
|
105
|
+
config = JSON.parse(raw);
|
|
106
|
+
} catch {
|
|
107
|
+
config = { invariants: [] };
|
|
108
|
+
}
|
|
109
|
+
const id = input.id ?? slugify(input.label);
|
|
110
|
+
if (config.invariants.some((inv) => inv.id === id)) {
|
|
111
|
+
throw new Error(`Invariant with id "${id}" already exists.`);
|
|
112
|
+
}
|
|
113
|
+
const invariant = {
|
|
114
|
+
id,
|
|
115
|
+
label: input.label,
|
|
116
|
+
enforcement: input.enforcement ?? "structural",
|
|
117
|
+
mutable: false
|
|
118
|
+
};
|
|
119
|
+
config.invariants.push(invariant);
|
|
120
|
+
await writeFile(invariantsPath, JSON.stringify(config, null, 2) + "\n");
|
|
121
|
+
const { loadWorldFromDirectory } = await import("./world-loader-Y6HMQH2D.js");
|
|
122
|
+
const world = await loadWorldFromDirectory(worldDir);
|
|
123
|
+
const report = validateWorld(world);
|
|
124
|
+
return {
|
|
125
|
+
type: "invariant",
|
|
126
|
+
id,
|
|
127
|
+
file: invariantsPath,
|
|
128
|
+
valid: report.summary.isHealthy,
|
|
129
|
+
findings: report.findings,
|
|
130
|
+
construct: invariant
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function classifyIntent(text) {
|
|
134
|
+
const lower = text.toLowerCase().trim();
|
|
135
|
+
const guardPatterns = [
|
|
136
|
+
/^block\b/,
|
|
137
|
+
/^prevent\b/,
|
|
138
|
+
/^deny\b/,
|
|
139
|
+
/^reject\b/,
|
|
140
|
+
/^disallow\b/,
|
|
141
|
+
/^forbid\b/,
|
|
142
|
+
/^stop\b/,
|
|
143
|
+
/^pause\b/,
|
|
144
|
+
/^warn\s+(when|if|on|before)\b/,
|
|
145
|
+
/^require\s+approval\b/,
|
|
146
|
+
/^flag\b/,
|
|
147
|
+
/^restrict\b/
|
|
148
|
+
];
|
|
149
|
+
const invariantPatterns = [
|
|
150
|
+
/must\s+(always|never)\b/,
|
|
151
|
+
/must\s+not\b/,
|
|
152
|
+
/shall\s+(always|never)\b/,
|
|
153
|
+
/can\s*not\s+(ever|drop|exceed|go)\b/,
|
|
154
|
+
/cannot\s+(ever|drop|exceed|go)\b/,
|
|
155
|
+
/\bmust\s+remain\b/,
|
|
156
|
+
/\balways\s+be\b/,
|
|
157
|
+
/\bnever\s+(exceed|drop|go|fall|be)\b/,
|
|
158
|
+
/\bfloor\b.*\bmust\b/,
|
|
159
|
+
/\bcap\b.*\bmust\b/,
|
|
160
|
+
/\bhard\s+limit\b/,
|
|
161
|
+
/\bguarantee\b/
|
|
162
|
+
];
|
|
163
|
+
const rulePatterns = [
|
|
164
|
+
/^if\b.*\bthen\b/,
|
|
165
|
+
/^when\b.*\b(reduce|increase|multiply|set|add|subtract)\b/,
|
|
166
|
+
/\b(reduce|increase|multiply|degrade|boost)\b.*\bby\b/,
|
|
167
|
+
/\b(viability|margin|score|trust|budget)\b.*\b(drop|rise|change|shift)/,
|
|
168
|
+
/\beffect\b/,
|
|
169
|
+
/\btrigger\b.*\bwhen\b/,
|
|
170
|
+
/\bcollapse\b.*\bif\b/
|
|
171
|
+
];
|
|
172
|
+
const guardScore = guardPatterns.filter((p) => p.test(lower)).length;
|
|
173
|
+
const invariantScore = invariantPatterns.filter((p) => p.test(lower)).length;
|
|
174
|
+
const ruleScore = rulePatterns.filter((p) => p.test(lower)).length;
|
|
175
|
+
const max = Math.max(guardScore, invariantScore, ruleScore);
|
|
176
|
+
if (max === 0) return "ambiguous";
|
|
177
|
+
const scores = [guardScore, invariantScore, ruleScore];
|
|
178
|
+
const winners = scores.filter((s) => s === max);
|
|
179
|
+
if (winners.length > 1) return "ambiguous";
|
|
180
|
+
if (guardScore === max) return "guard";
|
|
181
|
+
if (invariantScore === max) return "invariant";
|
|
182
|
+
return "rule";
|
|
183
|
+
}
|
|
184
|
+
function parseGuardDescription(text) {
|
|
185
|
+
const lower = text.toLowerCase().trim();
|
|
186
|
+
let enforcement = "block";
|
|
187
|
+
if (/^pause\b|require\s+approval/i.test(lower)) enforcement = "pause";
|
|
188
|
+
else if (/^warn\b|^flag\b/i.test(lower)) enforcement = "warn";
|
|
189
|
+
else if (/^block\b|^prevent\b|^deny\b|^reject\b|^forbid\b|^disallow\b|^stop\b/i.test(lower)) enforcement = "block";
|
|
190
|
+
const stripped = text.replace(/^(block|prevent|deny|reject|forbid|disallow|stop|pause|warn|flag|restrict)\s+(if\s+|when\s+|on\s+|before\s+)?/i, "").trim();
|
|
191
|
+
const words = stripped.toLowerCase().split(/\s+/).filter((w) => w.length > 2);
|
|
192
|
+
const patterns = [];
|
|
193
|
+
if (words.length > 0) {
|
|
194
|
+
patterns.push(`*${words.join("*")}*`);
|
|
195
|
+
if (words.length > 1) {
|
|
196
|
+
for (const word of words) {
|
|
197
|
+
patterns.push(`*${word}*`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
label: text,
|
|
203
|
+
enforcement,
|
|
204
|
+
intentPatterns: patterns.length > 0 ? patterns : ["*"],
|
|
205
|
+
description: text
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export {
|
|
210
|
+
addGuard,
|
|
211
|
+
addRule,
|
|
212
|
+
addInvariant,
|
|
213
|
+
classifyIntent,
|
|
214
|
+
parseGuardDescription
|
|
215
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import {
|
|
2
|
+
advancePlan,
|
|
3
|
+
evaluatePlan,
|
|
4
|
+
getPlanProgress
|
|
5
|
+
} from "./chunk-QLPTHTVB.js";
|
|
6
|
+
|
|
7
|
+
// src/adapters/shared.ts
|
|
8
|
+
var GovernanceBlockedError = class extends Error {
|
|
9
|
+
verdict;
|
|
10
|
+
constructor(verdict, message) {
|
|
11
|
+
super(message ?? `[NeuroVerse] BLOCKED: ${verdict.reason ?? verdict.ruleId ?? "governance rule"}`);
|
|
12
|
+
this.name = "GovernanceBlockedError";
|
|
13
|
+
this.verdict = verdict;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
function trackPlanProgress(event, state, callbacks) {
|
|
17
|
+
if (!state.activePlan) return;
|
|
18
|
+
const planVerdict = evaluatePlan(event, state.activePlan);
|
|
19
|
+
if (planVerdict.matchedStep) {
|
|
20
|
+
const advResult = advancePlan(state.activePlan, planVerdict.matchedStep);
|
|
21
|
+
if (advResult.success && advResult.plan) {
|
|
22
|
+
state.activePlan = advResult.plan;
|
|
23
|
+
state.engineOptions.plan = state.activePlan;
|
|
24
|
+
}
|
|
25
|
+
const progress = getPlanProgress(state.activePlan);
|
|
26
|
+
callbacks.onPlanProgress?.(progress);
|
|
27
|
+
if (progress.completed === progress.total) {
|
|
28
|
+
callbacks.onPlanComplete?.();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function extractScope(args) {
|
|
33
|
+
if (typeof args.path === "string") return args.path;
|
|
34
|
+
if (typeof args.file_path === "string") return args.file_path;
|
|
35
|
+
if (typeof args.filename === "string") return args.filename;
|
|
36
|
+
if (typeof args.url === "string") return args.url;
|
|
37
|
+
if (typeof args.command === "string") return args.command;
|
|
38
|
+
return void 0;
|
|
39
|
+
}
|
|
40
|
+
function buildEngineOptions(options, plan) {
|
|
41
|
+
return {
|
|
42
|
+
trace: options.trace ?? false,
|
|
43
|
+
level: options.level,
|
|
44
|
+
plan: plan ?? options.plan
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function defaultBlockMessage(verdict) {
|
|
48
|
+
return `Action blocked by governance policy: ${verdict.reason ?? "rule violation"}. Rule: ${verdict.ruleId ?? "unknown"}.`;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export {
|
|
52
|
+
GovernanceBlockedError,
|
|
53
|
+
trackPlanProgress,
|
|
54
|
+
extractScope,
|
|
55
|
+
buildEngineOptions,
|
|
56
|
+
defaultBlockMessage
|
|
57
|
+
};
|
|
@@ -4,13 +4,15 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
loadConfig
|
|
6
6
|
} from "./chunk-OT6PXH54.js";
|
|
7
|
-
import {
|
|
8
|
-
emitWorldDefinition,
|
|
9
|
-
parseWorldMarkdown
|
|
10
|
-
} from "./chunk-XPDMYECO.js";
|
|
11
7
|
import {
|
|
12
8
|
validateWorld
|
|
13
9
|
} from "./chunk-7P3S7MAY.js";
|
|
10
|
+
import {
|
|
11
|
+
parseWorldMarkdown
|
|
12
|
+
} from "./chunk-EMQDLDAF.js";
|
|
13
|
+
import {
|
|
14
|
+
emitWorldDefinition
|
|
15
|
+
} from "./chunk-PVTQQS3Y.js";
|
|
14
16
|
|
|
15
17
|
// src/engine/derive-normalizer.ts
|
|
16
18
|
function findSections(lines) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
evaluateGuard
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-W7LLXRGY.js";
|
|
4
4
|
|
|
5
5
|
// src/engine/audit-logger.ts
|
|
6
6
|
var FileAuditLogger = class {
|
|
@@ -38,12 +38,22 @@ var FileAuditLogger = class {
|
|
|
38
38
|
};
|
|
39
39
|
var ConsoleAuditLogger = class {
|
|
40
40
|
log(event) {
|
|
41
|
-
const
|
|
41
|
+
const iconMap = {
|
|
42
|
+
"ALLOW": "\u25CF",
|
|
43
|
+
"BLOCK": "\u25CB",
|
|
44
|
+
"PAUSE": "\u25D1",
|
|
45
|
+
"MODIFY": "\u25D0",
|
|
46
|
+
"PENALIZE": "\u25CC",
|
|
47
|
+
"REWARD": "\u25C9",
|
|
48
|
+
"NEUTRAL": "\u25EF"
|
|
49
|
+
};
|
|
50
|
+
const icon = iconMap[event.decision] ?? "\xB7";
|
|
42
51
|
const ts = event.timestamp.split("T")[1]?.replace("Z", "") ?? event.timestamp;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
`
|
|
46
|
-
)
|
|
52
|
+
let line = `[${ts}] ${icon} ${event.decision.padEnd(10)} ${event.actor ?? "\u2014"} \u2192 ${event.intent}`;
|
|
53
|
+
if (event.reason) line += ` (${event.reason})`;
|
|
54
|
+
if (event.consequence) line += ` [consequence: ${event.consequence.description}]`;
|
|
55
|
+
if (event.reward) line += ` [reward: ${event.reward.description}]`;
|
|
56
|
+
process.stderr.write(line + "\n");
|
|
47
57
|
}
|
|
48
58
|
};
|
|
49
59
|
var CompositeAuditLogger = class {
|
|
@@ -66,7 +76,7 @@ var CompositeAuditLogger = class {
|
|
|
66
76
|
}
|
|
67
77
|
};
|
|
68
78
|
function verdictToAuditEvent(event, verdict) {
|
|
69
|
-
|
|
79
|
+
const auditEvent = {
|
|
70
80
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
71
81
|
worldId: verdict.evidence.worldId,
|
|
72
82
|
worldName: verdict.evidence.worldName,
|
|
@@ -88,6 +98,17 @@ function verdictToAuditEvent(event, verdict) {
|
|
|
88
98
|
durationMs: verdict.trace?.durationMs,
|
|
89
99
|
args: event.args
|
|
90
100
|
};
|
|
101
|
+
if (verdict.consequence) {
|
|
102
|
+
auditEvent.consequence = verdict.consequence;
|
|
103
|
+
}
|
|
104
|
+
if (verdict.reward) {
|
|
105
|
+
auditEvent.reward = verdict.reward;
|
|
106
|
+
}
|
|
107
|
+
if (verdict.intentRecord) {
|
|
108
|
+
auditEvent.originalIntent = verdict.intentRecord.originalIntent;
|
|
109
|
+
auditEvent.finalAction = verdict.intentRecord.finalAction;
|
|
110
|
+
}
|
|
111
|
+
return auditEvent;
|
|
91
112
|
}
|
|
92
113
|
function createGovernanceEngine(world, options = {}) {
|
|
93
114
|
const { auditLogger, auditArgs, ...engineOptions } = options;
|
|
@@ -140,16 +161,22 @@ function summarizeAuditEvents(events) {
|
|
|
140
161
|
const allowed = events.filter((e) => e.decision === "ALLOW").length;
|
|
141
162
|
const blocked = events.filter((e) => e.decision === "BLOCK").length;
|
|
142
163
|
const paused = events.filter((e) => e.decision === "PAUSE").length;
|
|
164
|
+
const modified = events.filter((e) => e.decision === "MODIFY").length;
|
|
165
|
+
const penalized = events.filter((e) => e.decision === "PENALIZE").length;
|
|
166
|
+
const rewarded = events.filter((e) => e.decision === "REWARD").length;
|
|
167
|
+
const neutral = events.filter((e) => e.decision === "NEUTRAL").length;
|
|
143
168
|
const actorSet = /* @__PURE__ */ new Set();
|
|
144
169
|
for (const e of events) {
|
|
145
170
|
if (e.actor) actorSet.add(e.actor);
|
|
146
171
|
}
|
|
147
172
|
const intentMap = /* @__PURE__ */ new Map();
|
|
148
173
|
for (const e of events) {
|
|
149
|
-
const entry = intentMap.get(e.intent) ?? { count: 0, blocked: 0, paused: 0 };
|
|
174
|
+
const entry = intentMap.get(e.intent) ?? { count: 0, blocked: 0, paused: 0, penalized: 0, rewarded: 0 };
|
|
150
175
|
entry.count++;
|
|
151
176
|
if (e.decision === "BLOCK") entry.blocked++;
|
|
152
177
|
if (e.decision === "PAUSE") entry.paused++;
|
|
178
|
+
if (e.decision === "PENALIZE") entry.penalized++;
|
|
179
|
+
if (e.decision === "REWARD") entry.rewarded++;
|
|
153
180
|
intentMap.set(e.intent, entry);
|
|
154
181
|
}
|
|
155
182
|
const topIntents = [...intentMap.entries()].map(([intent, data]) => ({ intent, ...data })).sort((a, b) => b.count - a.count);
|
|
@@ -163,16 +190,28 @@ function summarizeAuditEvents(events) {
|
|
|
163
190
|
}
|
|
164
191
|
}
|
|
165
192
|
const topRules = [...ruleMap.entries()].map(([ruleId, count]) => ({ ruleId, count })).sort((a, b) => b.count - a.count);
|
|
193
|
+
const redirected = blocked + paused + modified + penalized;
|
|
194
|
+
const total = events.length;
|
|
166
195
|
return {
|
|
167
|
-
totalActions:
|
|
196
|
+
totalActions: total,
|
|
168
197
|
allowed,
|
|
169
198
|
blocked,
|
|
170
199
|
paused,
|
|
200
|
+
modified,
|
|
201
|
+
penalized,
|
|
202
|
+
rewarded,
|
|
203
|
+
neutral,
|
|
171
204
|
actors: [...actorSet],
|
|
172
205
|
topIntents,
|
|
173
206
|
topRules,
|
|
174
207
|
firstEvent: events[0]?.timestamp ?? "",
|
|
175
|
-
lastEvent: events[events.length - 1]?.timestamp ?? ""
|
|
208
|
+
lastEvent: events[events.length - 1]?.timestamp ?? "",
|
|
209
|
+
behavioralEconomy: {
|
|
210
|
+
totalPenalties: penalized,
|
|
211
|
+
totalRewards: rewarded,
|
|
212
|
+
netPressure: rewarded - penalized,
|
|
213
|
+
redirectionRate: total > 0 ? redirected / total : 0
|
|
214
|
+
}
|
|
176
215
|
};
|
|
177
216
|
}
|
|
178
217
|
|
|
@@ -4,15 +4,15 @@ import {
|
|
|
4
4
|
} from "./chunk-AKW5YVCE.js";
|
|
5
5
|
import {
|
|
6
6
|
evaluateGuard
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-W7LLXRGY.js";
|
|
8
8
|
import {
|
|
9
9
|
advancePlan,
|
|
10
10
|
evaluatePlan,
|
|
11
11
|
getPlanProgress
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-QLPTHTVB.js";
|
|
13
13
|
import {
|
|
14
14
|
loadWorld
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-CTZHONLA.js";
|
|
16
16
|
|
|
17
17
|
// src/runtime/mcp-server.ts
|
|
18
18
|
import { execSync } from "child_process";
|
|
@@ -200,9 +200,17 @@ var McpGovernanceServer = class {
|
|
|
200
200
|
`);
|
|
201
201
|
}
|
|
202
202
|
let buffer = "";
|
|
203
|
+
const MAX_BUFFER_SIZE = 10 * 1024 * 1024;
|
|
204
|
+
const MAX_CONTENT_LENGTH = 10 * 1024 * 1024;
|
|
203
205
|
process.stdin.setEncoding("utf-8");
|
|
204
206
|
process.stdin.on("data", (chunk) => {
|
|
205
207
|
buffer += chunk;
|
|
208
|
+
if (buffer.length > MAX_BUFFER_SIZE) {
|
|
209
|
+
process.stderr.write(`[neuroverse-mcp] Buffer exceeded ${MAX_BUFFER_SIZE} bytes, dropping.
|
|
210
|
+
`);
|
|
211
|
+
buffer = "";
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
206
214
|
while (buffer.length > 0) {
|
|
207
215
|
const headerEnd = buffer.indexOf("\r\n\r\n");
|
|
208
216
|
if (headerEnd === -1) break;
|
|
@@ -217,6 +225,12 @@ var McpGovernanceServer = class {
|
|
|
217
225
|
continue;
|
|
218
226
|
}
|
|
219
227
|
const contentLength = parseInt(contentLengthMatch[1], 10);
|
|
228
|
+
if (isNaN(contentLength) || contentLength < 0 || contentLength > MAX_CONTENT_LENGTH) {
|
|
229
|
+
process.stderr.write(`[neuroverse-mcp] Invalid Content-Length: ${contentLengthMatch[1]}, skipping.
|
|
230
|
+
`);
|
|
231
|
+
buffer = "";
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
220
234
|
const bodyStart = headerEnd + 4;
|
|
221
235
|
const bodyEnd = bodyStart + contentLength;
|
|
222
236
|
if (buffer.length < bodyEnd) break;
|