@neuroverseos/governance 0.1.0 → 0.1.2
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/LICENSE.md +190 -0
- package/README.md +472 -115
- package/dist/adapters/express.cjs +874 -0
- package/dist/adapters/express.d.cts +66 -0
- package/dist/adapters/express.d.ts +66 -0
- package/dist/adapters/express.js +10 -0
- package/dist/adapters/index.cjs +1166 -0
- package/dist/adapters/index.d.cts +5 -0
- package/dist/adapters/index.d.ts +5 -0
- package/dist/adapters/index.js +40 -0
- package/dist/adapters/langchain.cjs +861 -0
- package/dist/adapters/langchain.d.cts +82 -0
- package/dist/adapters/langchain.d.ts +82 -0
- package/dist/adapters/langchain.js +14 -0
- package/dist/adapters/openai.cjs +891 -0
- package/dist/adapters/openai.d.cts +92 -0
- package/dist/adapters/openai.d.ts +92 -0
- package/dist/adapters/openai.js +14 -0
- package/dist/adapters/openclaw.cjs +883 -0
- package/dist/adapters/openclaw.d.cts +92 -0
- package/dist/adapters/openclaw.d.ts +92 -0
- package/dist/adapters/openclaw.js +14 -0
- package/dist/bootstrap-H4HHKQ5G.js +113 -0
- package/dist/build-73KAVHEY.js +308 -0
- package/dist/chunk-4NGDRRQH.js +10 -0
- package/dist/chunk-B4NF3OLW.js +673 -0
- package/dist/chunk-BUWWN2NX.js +192 -0
- package/dist/chunk-CROPZ75A.js +107 -0
- package/dist/chunk-D7BGWV2J.js +620 -0
- package/dist/chunk-EIUHJXBB.js +340 -0
- package/dist/chunk-EQXFOKH2.js +85 -0
- package/dist/chunk-FYPYZFV5.js +187 -0
- package/dist/chunk-FYS2CBUW.js +304 -0
- package/dist/chunk-FZQCRGUU.js +115 -0
- package/dist/chunk-I3RRAYK2.js +11 -0
- package/dist/chunk-ITJ3LCPG.js +225 -0
- package/dist/chunk-M3TZFGHO.js +79 -0
- package/dist/chunk-MWDQ4MJB.js +11 -0
- package/dist/chunk-O5OMJMIE.js +590 -0
- package/dist/chunk-T4X42QXC.js +121 -0
- package/dist/chunk-XPDMYECO.js +642 -0
- package/dist/chunk-Z2S2HIV5.js +100 -0
- package/dist/cli/neuroverse.cjs +5864 -0
- package/dist/cli/neuroverse.d.cts +1 -0
- package/dist/cli/neuroverse.d.ts +1 -0
- package/dist/cli/neuroverse.js +128 -0
- package/dist/configure-ai-46JVG56I.js +129 -0
- package/dist/derive-6NAEWLM5.js +150 -0
- package/dist/explain-3B3VB6TL.js +69 -0
- package/dist/guard-67Y66P3I.js +82 -0
- package/dist/guard-contract-D_RQz9kt.d.cts +529 -0
- package/dist/guard-contract-D_RQz9kt.d.ts +529 -0
- package/dist/impact-CHERK3O6.js +57 -0
- package/dist/improve-YG6I6ERG.js +84 -0
- package/dist/index.cjs +4227 -0
- package/dist/index.d.cts +1147 -0
- package/dist/index.d.ts +1139 -25
- package/dist/index.js +318 -1159
- package/dist/init-Z66T6TDI.js +142 -0
- package/dist/simulate-ETHHINZ4.js +107 -0
- package/dist/trace-3YODSSIP.js +164 -0
- package/dist/validate-UVE6GKQU.js +72 -0
- package/dist/validate-engine-657D75OG.js +6 -0
- package/dist/world-WLNHL5XC.js +298 -0
- package/dist/worlds/derivation-world.nv-world.md +278 -0
- package/package.json +74 -26
- package/LICENSE +0 -21
- package/dist/audit-logger.d.ts +0 -38
- package/dist/audit-logger.d.ts.map +0 -1
- package/dist/audit-logger.js +0 -100
- package/dist/audit-logger.js.map +0 -1
- package/dist/condition-engine.d.ts +0 -16
- package/dist/condition-engine.d.ts.map +0 -1
- package/dist/condition-engine.js +0 -186
- package/dist/condition-engine.js.map +0 -1
- package/dist/drift-monitor.d.ts +0 -81
- package/dist/drift-monitor.d.ts.map +0 -1
- package/dist/drift-monitor.js +0 -228
- package/dist/drift-monitor.js.map +0 -1
- package/dist/governance-engine.d.ts +0 -131
- package/dist/governance-engine.d.ts.map +0 -1
- package/dist/governance-engine.js +0 -660
- package/dist/governance-engine.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/types.d.ts +0 -196
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -9
- package/dist/types.js.map +0 -1
- package/dist/world-bootstrap.d.ts +0 -31
- package/dist/world-bootstrap.d.ts.map +0 -1
- package/dist/world-bootstrap.js +0 -415
- package/dist/world-bootstrap.js.map +0 -1
- package/openclaw.plugin.json +0 -59
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
// src/engine/explain-engine.ts
|
|
2
|
+
function detectTensions(rules) {
|
|
3
|
+
const increases = /* @__PURE__ */ new Map();
|
|
4
|
+
const decreases = /* @__PURE__ */ new Map();
|
|
5
|
+
for (const rule of rules) {
|
|
6
|
+
const allEffects = collectAllEffects(rule);
|
|
7
|
+
for (const effect of allEffects) {
|
|
8
|
+
const target = effect.target;
|
|
9
|
+
const isIncrease = effect.operation === "add" || effect.operation === "multiply" && typeof effect.value === "number" && effect.value > 1;
|
|
10
|
+
const isDecrease = effect.operation === "subtract" || effect.operation === "multiply" && typeof effect.value === "number" && effect.value < 1;
|
|
11
|
+
if (isIncrease) {
|
|
12
|
+
if (!increases.has(target)) increases.set(target, []);
|
|
13
|
+
increases.get(target).push(rule.label);
|
|
14
|
+
}
|
|
15
|
+
if (isDecrease) {
|
|
16
|
+
if (!decreases.has(target)) decreases.set(target, []);
|
|
17
|
+
decreases.get(target).push(rule.label);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const tensions = [];
|
|
22
|
+
for (const [variable, incRules] of increases) {
|
|
23
|
+
const decRules = decreases.get(variable);
|
|
24
|
+
if (decRules && decRules.length > 0) {
|
|
25
|
+
tensions.push({
|
|
26
|
+
variable,
|
|
27
|
+
increasedBy: incRules,
|
|
28
|
+
decreasedBy: decRules
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return tensions;
|
|
33
|
+
}
|
|
34
|
+
function collectAllEffects(rule) {
|
|
35
|
+
const effects = [...rule.effects ?? []];
|
|
36
|
+
for (const ce of rule.effects_conditional ?? []) {
|
|
37
|
+
effects.push(...ce.effects);
|
|
38
|
+
}
|
|
39
|
+
return effects;
|
|
40
|
+
}
|
|
41
|
+
function explainWorld(world) {
|
|
42
|
+
const dynamics = [...world.rules].sort((a, b) => a.order - b.order).map((rule) => {
|
|
43
|
+
const allEffects = collectAllEffects(rule);
|
|
44
|
+
return {
|
|
45
|
+
ruleId: rule.id,
|
|
46
|
+
label: rule.label,
|
|
47
|
+
severity: rule.severity,
|
|
48
|
+
triggerDescription: rule.causal_translation?.trigger_text ?? describeTriggers(rule),
|
|
49
|
+
effectDescription: rule.causal_translation?.effect_text ?? describeEffects(allEffects),
|
|
50
|
+
targets: [...new Set(allEffects.map((e) => e.target))]
|
|
51
|
+
};
|
|
52
|
+
});
|
|
53
|
+
const stateVariables = Object.entries(world.stateSchema.variables ?? {}).map(
|
|
54
|
+
([name, v]) => ({
|
|
55
|
+
name,
|
|
56
|
+
label: v.label || name,
|
|
57
|
+
type: v.type,
|
|
58
|
+
defaultValue: v.default,
|
|
59
|
+
range: v.type === "number" && v.min !== void 0 && v.max !== void 0 ? `${v.min}\u2013${v.max}` : v.type === "enum" && v.options ? v.options.join(", ") : void 0
|
|
60
|
+
})
|
|
61
|
+
);
|
|
62
|
+
const invariants = world.invariants.map((inv) => ({
|
|
63
|
+
id: inv.id,
|
|
64
|
+
label: inv.label,
|
|
65
|
+
enforcement: inv.enforcement
|
|
66
|
+
}));
|
|
67
|
+
const gates = (world.gates.viability_classification ?? []).map((g) => ({
|
|
68
|
+
status: g.status,
|
|
69
|
+
field: g.field,
|
|
70
|
+
threshold: `${g.operator} ${g.value}`
|
|
71
|
+
}));
|
|
72
|
+
const tensions = detectTensions(world.rules);
|
|
73
|
+
const outcomes = (world.outcomes.computed_outcomes ?? []).map((o) => ({
|
|
74
|
+
id: o.id,
|
|
75
|
+
label: o.label,
|
|
76
|
+
type: o.type,
|
|
77
|
+
primary: o.primary ?? false
|
|
78
|
+
}));
|
|
79
|
+
const stats = {
|
|
80
|
+
invariants: world.invariants.length,
|
|
81
|
+
stateVariables: Object.keys(world.stateSchema.variables ?? {}).length,
|
|
82
|
+
rules: world.rules.length,
|
|
83
|
+
gates: (world.gates.viability_classification ?? []).length,
|
|
84
|
+
outcomes: (world.outcomes.computed_outcomes ?? []).length,
|
|
85
|
+
assumptions: Object.keys(world.assumptions.profiles ?? {}).length
|
|
86
|
+
};
|
|
87
|
+
return {
|
|
88
|
+
worldName: world.world.name,
|
|
89
|
+
worldId: world.world.world_id,
|
|
90
|
+
thesis: world.world.thesis,
|
|
91
|
+
dynamics,
|
|
92
|
+
stateVariables,
|
|
93
|
+
invariants,
|
|
94
|
+
gates,
|
|
95
|
+
tensions,
|
|
96
|
+
outcomes,
|
|
97
|
+
stats
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
function describeTriggers(rule) {
|
|
101
|
+
if (!rule.triggers || rule.triggers.length === 0) return "Always active";
|
|
102
|
+
return rule.triggers.map((t) => `${t.field} ${t.operator} ${t.value}`).join(" AND ");
|
|
103
|
+
}
|
|
104
|
+
function describeEffects(effects) {
|
|
105
|
+
if (effects.length === 0) return "No direct effects";
|
|
106
|
+
return effects.map((e) => {
|
|
107
|
+
switch (e.operation) {
|
|
108
|
+
case "multiply":
|
|
109
|
+
return `${e.target} scaled by ${e.value}`;
|
|
110
|
+
case "add":
|
|
111
|
+
return `${e.target} increased by ${e.value}`;
|
|
112
|
+
case "subtract":
|
|
113
|
+
return `${e.target} decreased by ${e.value}`;
|
|
114
|
+
case "set":
|
|
115
|
+
return `${e.target} set to ${e.value}`;
|
|
116
|
+
case "set_boolean":
|
|
117
|
+
return `${e.target} set to ${e.value}`;
|
|
118
|
+
default:
|
|
119
|
+
return `${e.target} ${e.operation} ${e.value}`;
|
|
120
|
+
}
|
|
121
|
+
}).join("; ");
|
|
122
|
+
}
|
|
123
|
+
function renderExplainText(output) {
|
|
124
|
+
const lines = [];
|
|
125
|
+
lines.push(`WORLD: ${output.worldName}`);
|
|
126
|
+
lines.push(`ID: ${output.worldId}`);
|
|
127
|
+
lines.push("");
|
|
128
|
+
if (output.thesis) {
|
|
129
|
+
lines.push("THESIS");
|
|
130
|
+
lines.push(` ${output.thesis}`);
|
|
131
|
+
lines.push("");
|
|
132
|
+
}
|
|
133
|
+
lines.push("STRUCTURE");
|
|
134
|
+
lines.push(` ${output.stats.invariants} invariants, ${output.stats.stateVariables} state variables, ${output.stats.rules} rules`);
|
|
135
|
+
lines.push(` ${output.stats.gates} viability gates, ${output.stats.outcomes} outcomes, ${output.stats.assumptions} assumption profiles`);
|
|
136
|
+
lines.push("");
|
|
137
|
+
if (output.dynamics.length > 0) {
|
|
138
|
+
lines.push("KEY DYNAMICS");
|
|
139
|
+
for (const d of output.dynamics) {
|
|
140
|
+
const severity = d.severity === "structural" ? "[structural]" : d.severity === "advantage" ? "[advantage]" : "[degradation]";
|
|
141
|
+
lines.push(` ${d.label} ${severity}`);
|
|
142
|
+
lines.push(` When: ${d.triggerDescription}`);
|
|
143
|
+
lines.push(` Then: ${d.effectDescription}`);
|
|
144
|
+
}
|
|
145
|
+
lines.push("");
|
|
146
|
+
}
|
|
147
|
+
if (output.tensions.length > 0) {
|
|
148
|
+
lines.push("DRAMATIC TENSIONS");
|
|
149
|
+
for (const t of output.tensions) {
|
|
150
|
+
lines.push(` ${t.variable}:`);
|
|
151
|
+
lines.push(` Increased by: ${t.increasedBy.join(", ")}`);
|
|
152
|
+
lines.push(` Decreased by: ${t.decreasedBy.join(", ")}`);
|
|
153
|
+
}
|
|
154
|
+
lines.push("");
|
|
155
|
+
}
|
|
156
|
+
if (output.stateVariables.length > 0) {
|
|
157
|
+
lines.push("STATE VARIABLES");
|
|
158
|
+
for (const v of output.stateVariables) {
|
|
159
|
+
const range = v.range ? ` (${v.range})` : "";
|
|
160
|
+
lines.push(` ${v.label}: ${v.type}, default ${v.defaultValue}${range}`);
|
|
161
|
+
}
|
|
162
|
+
lines.push("");
|
|
163
|
+
}
|
|
164
|
+
if (output.invariants.length > 0) {
|
|
165
|
+
lines.push("INVARIANTS (cannot change)");
|
|
166
|
+
for (const inv of output.invariants) {
|
|
167
|
+
lines.push(` ${inv.label} [${inv.enforcement}]`);
|
|
168
|
+
}
|
|
169
|
+
lines.push("");
|
|
170
|
+
}
|
|
171
|
+
if (output.gates.length > 0) {
|
|
172
|
+
lines.push("VIABILITY GATES");
|
|
173
|
+
for (const g of output.gates) {
|
|
174
|
+
lines.push(` ${g.status}: ${g.field} ${g.threshold}`);
|
|
175
|
+
}
|
|
176
|
+
lines.push("");
|
|
177
|
+
}
|
|
178
|
+
if (output.outcomes.length > 0) {
|
|
179
|
+
lines.push("OUTCOMES");
|
|
180
|
+
for (const o of output.outcomes) {
|
|
181
|
+
const primary = o.primary ? " [primary]" : "";
|
|
182
|
+
lines.push(` ${o.label} (${o.type})${primary}`);
|
|
183
|
+
}
|
|
184
|
+
lines.push("");
|
|
185
|
+
}
|
|
186
|
+
return lines.join("\n");
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export {
|
|
190
|
+
explainWorld,
|
|
191
|
+
renderExplainText
|
|
192
|
+
};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import {
|
|
2
|
+
evaluateGuard
|
|
3
|
+
} from "./chunk-B4NF3OLW.js";
|
|
4
|
+
import {
|
|
5
|
+
loadWorld
|
|
6
|
+
} from "./chunk-M3TZFGHO.js";
|
|
7
|
+
|
|
8
|
+
// src/adapters/openclaw.ts
|
|
9
|
+
var GovernanceBlockedError = class extends Error {
|
|
10
|
+
verdict;
|
|
11
|
+
action;
|
|
12
|
+
constructor(verdict, action) {
|
|
13
|
+
super(`[NeuroVerse] BLOCKED: ${verdict.reason ?? verdict.ruleId ?? "governance rule"}`);
|
|
14
|
+
this.name = "GovernanceBlockedError";
|
|
15
|
+
this.verdict = verdict;
|
|
16
|
+
this.action = action;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
function defaultMapAction(action, direction) {
|
|
20
|
+
return {
|
|
21
|
+
intent: action.type,
|
|
22
|
+
tool: action.tool ?? action.type,
|
|
23
|
+
args: action.input,
|
|
24
|
+
direction,
|
|
25
|
+
scope: typeof action.input?.path === "string" ? action.input.path : typeof action.input?.url === "string" ? action.input.url : void 0
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
var NeuroVersePlugin = class {
|
|
29
|
+
name = "neuroverse-governance";
|
|
30
|
+
world;
|
|
31
|
+
options;
|
|
32
|
+
engineOptions;
|
|
33
|
+
mapAction;
|
|
34
|
+
constructor(world, options = {}) {
|
|
35
|
+
this.world = world;
|
|
36
|
+
this.options = options;
|
|
37
|
+
this.engineOptions = {
|
|
38
|
+
trace: options.trace ?? false,
|
|
39
|
+
level: options.level
|
|
40
|
+
};
|
|
41
|
+
this.mapAction = options.mapAction ?? defaultMapAction;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Evaluate an action before execution.
|
|
45
|
+
*
|
|
46
|
+
* @throws GovernanceBlockedError if BLOCKED
|
|
47
|
+
* @returns HookResult with verdict details
|
|
48
|
+
*/
|
|
49
|
+
beforeAction(action) {
|
|
50
|
+
const event = this.mapAction(action, "input");
|
|
51
|
+
const verdict = evaluateGuard(event, this.world, this.engineOptions);
|
|
52
|
+
const result = {
|
|
53
|
+
allowed: verdict.status === "ALLOW",
|
|
54
|
+
verdict,
|
|
55
|
+
action
|
|
56
|
+
};
|
|
57
|
+
this.options.onEvaluate?.(result);
|
|
58
|
+
if (verdict.status === "BLOCK") {
|
|
59
|
+
throw new GovernanceBlockedError(verdict, action);
|
|
60
|
+
}
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Evaluate an action's output (post-execution governance).
|
|
65
|
+
* Only runs if evaluateOutputs is enabled.
|
|
66
|
+
*
|
|
67
|
+
* @returns HookResult or null if output evaluation is disabled
|
|
68
|
+
*/
|
|
69
|
+
afterAction(action, _output) {
|
|
70
|
+
if (!this.options.evaluateOutputs) return null;
|
|
71
|
+
const event = this.mapAction(action, "output");
|
|
72
|
+
const verdict = evaluateGuard(event, this.world, this.engineOptions);
|
|
73
|
+
const result = {
|
|
74
|
+
allowed: verdict.status === "ALLOW",
|
|
75
|
+
verdict,
|
|
76
|
+
action
|
|
77
|
+
};
|
|
78
|
+
this.options.onEvaluate?.(result);
|
|
79
|
+
if (verdict.status === "BLOCK") {
|
|
80
|
+
throw new GovernanceBlockedError(verdict, action);
|
|
81
|
+
}
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Get the plugin hooks object for agent.use().
|
|
86
|
+
*/
|
|
87
|
+
hooks() {
|
|
88
|
+
return {
|
|
89
|
+
beforeAction: (action) => this.beforeAction(action),
|
|
90
|
+
afterAction: (action, output) => this.afterAction(action, output)
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
async function createNeuroVersePlugin(worldPath, options) {
|
|
95
|
+
const world = await loadWorld(worldPath);
|
|
96
|
+
return new NeuroVersePlugin(world, options);
|
|
97
|
+
}
|
|
98
|
+
function createNeuroVersePluginFromWorld(world, options) {
|
|
99
|
+
return new NeuroVersePlugin(world, options);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export {
|
|
103
|
+
GovernanceBlockedError,
|
|
104
|
+
NeuroVersePlugin,
|
|
105
|
+
createNeuroVersePlugin,
|
|
106
|
+
createNeuroVersePluginFromWorld
|
|
107
|
+
};
|