@neuroverseos/governance 0.3.1 → 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 +343 -248
- package/dist/adapters/autoresearch.cjs +1345 -0
- package/dist/adapters/autoresearch.d.cts +111 -0
- package/dist/adapters/autoresearch.d.ts +111 -0
- package/dist/adapters/autoresearch.js +12 -0
- 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 +1253 -0
- package/dist/adapters/express.d.cts +66 -0
- package/dist/adapters/express.d.ts +66 -0
- package/dist/adapters/express.js +12 -0
- package/dist/adapters/index.cjs +2112 -0
- package/dist/adapters/index.d.cts +8 -0
- package/dist/adapters/index.d.ts +8 -0
- package/dist/adapters/index.js +68 -0
- package/dist/adapters/langchain.cjs +1315 -0
- package/dist/adapters/langchain.d.cts +89 -0
- package/dist/adapters/langchain.d.ts +89 -0
- package/dist/adapters/langchain.js +17 -0
- package/dist/adapters/openai.cjs +1345 -0
- package/dist/adapters/openai.d.cts +99 -0
- package/dist/adapters/openai.d.ts +99 -0
- package/dist/adapters/openai.js +17 -0
- package/dist/adapters/openclaw.cjs +1337 -0
- package/dist/adapters/openclaw.d.cts +99 -0
- package/dist/adapters/openclaw.d.ts +99 -0
- package/dist/adapters/openclaw.js +17 -0
- package/dist/add-ROOZLU62.js +314 -0
- package/dist/behavioral-MJO34S6Q.js +118 -0
- package/dist/bootstrap-CQRZVOXK.js +116 -0
- 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-QKOBBC23.js +341 -0
- package/dist/chunk-3WQLXYTP.js +91 -0
- package/dist/chunk-4FLICVVA.js +119 -0
- package/dist/chunk-4NGDRRQH.js +10 -0
- package/dist/chunk-5TPFNWRU.js +215 -0
- package/dist/chunk-5U2MQO5P.js +57 -0
- package/dist/chunk-6CZSKEY5.js +164 -0
- package/dist/chunk-6S5CFQXY.js +624 -0
- package/dist/chunk-7P3S7MAY.js +1090 -0
- package/dist/chunk-A5W4GNQO.js +130 -0
- package/dist/chunk-A7GKPPU7.js +226 -0
- package/dist/chunk-AKW5YVCE.js +96 -0
- package/dist/chunk-B6OXJLJ5.js +622 -0
- package/dist/chunk-BNKJPUPQ.js +113 -0
- package/dist/chunk-BQZMOEML.js +43 -0
- package/dist/chunk-CNSO6XW5.js +207 -0
- package/dist/chunk-CTZHONLA.js +135 -0
- package/dist/chunk-D2UCV5AK.js +326 -0
- package/dist/chunk-EMQDLDAF.js +458 -0
- package/dist/chunk-F66BVUYB.js +340 -0
- package/dist/chunk-G7DJ6VOD.js +101 -0
- package/dist/chunk-I3RRAYK2.js +11 -0
- package/dist/chunk-IS4WUH6Y.js +363 -0
- package/dist/chunk-MH7BT4VH.js +15 -0
- package/dist/chunk-O5ABKEA7.js +304 -0
- package/dist/chunk-OT6PXH54.js +61 -0
- package/dist/chunk-PVTQQS3Y.js +186 -0
- package/dist/chunk-Q6O7ZLO2.js +62 -0
- package/dist/chunk-QLPTHTVB.js +253 -0
- package/dist/chunk-QWGCMQQD.js +16 -0
- package/dist/chunk-QXBFT7NI.js +201 -0
- package/dist/chunk-TG6SEF24.js +246 -0
- package/dist/chunk-U6U7EJZL.js +177 -0
- package/dist/chunk-W7LLXRGY.js +830 -0
- package/dist/chunk-ZJTDUCC2.js +194 -0
- package/dist/chunk-ZWI3NIXK.js +314 -0
- package/dist/cli/neuroverse.cjs +14191 -0
- package/dist/cli/neuroverse.d.cts +1 -0
- package/dist/cli/neuroverse.d.ts +1 -0
- package/dist/cli/neuroverse.js +227 -0
- package/dist/cli/plan.cjs +2439 -0
- package/dist/cli/plan.d.cts +20 -0
- package/dist/cli/plan.d.ts +20 -0
- package/dist/cli/plan.js +353 -0
- package/dist/cli/run.cjs +2001 -0
- package/dist/cli/run.d.cts +20 -0
- package/dist/cli/run.d.ts +20 -0
- package/dist/cli/run.js +143 -0
- package/dist/configure-ai-6TZ3MCSI.js +132 -0
- package/dist/decision-flow-M63D47LO.js +61 -0
- package/dist/demo-G43RLCPK.js +469 -0
- package/dist/derive-FJZVIPUZ.js +153 -0
- package/dist/doctor-6BC6X2VO.js +173 -0
- package/dist/equity-penalties-SG5IZQ7I.js +244 -0
- package/dist/explain-RHBU2GBR.js +51 -0
- package/dist/guard-AJCCGZMF.js +92 -0
- package/dist/guard-contract-DqFcTScd.d.cts +821 -0
- package/dist/guard-contract-DqFcTScd.d.ts +821 -0
- package/dist/guard-engine-PNR6MHCM.js +10 -0
- package/dist/impact-3XVDSCBU.js +59 -0
- package/dist/improve-TQP4ECSY.js +66 -0
- package/dist/index.cjs +7591 -0
- package/dist/index.d.cts +2195 -0
- package/dist/index.d.ts +2195 -0
- package/dist/index.js +472 -0
- package/dist/infer-world-IFXCACJ5.js +543 -0
- package/dist/init-FYPV4SST.js +144 -0
- package/dist/init-world-TI7ARHBT.js +223 -0
- package/dist/mcp-server-5Y3ZM7TV.js +13 -0
- package/dist/model-adapter-VXEKB4LS.js +11 -0
- package/dist/playground-VZBNPPBO.js +560 -0
- package/dist/redteam-MZPZD3EF.js +357 -0
- 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-LJXYBC6M.js +83 -0
- package/dist/test-BOOR4A5F.js +217 -0
- package/dist/trace-PKV4KX56.js +166 -0
- package/dist/validate-RALX7CZS.js +81 -0
- package/dist/validate-engine-7ZXFVGF2.js +7 -0
- package/dist/viz/assets/index-B8SaeJZZ.js +23 -0
- package/dist/viz/index.html +23 -0
- package/dist/world-BIP4GZBZ.js +376 -0
- package/dist/world-loader-Y6HMQH2D.js +13 -0
- package/dist/worlds/autoresearch.nv-world.md +230 -0
- package/dist/worlds/coding-agent.nv-world.md +211 -0
- package/dist/worlds/derivation-world.nv-world.md +278 -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 +16 -3
- package/simulate.html +4 -336
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
import {
|
|
2
|
+
validateWorld
|
|
3
|
+
} from "./chunk-7P3S7MAY.js";
|
|
4
|
+
import {
|
|
5
|
+
simulateWorld
|
|
6
|
+
} from "./chunk-ZWI3NIXK.js";
|
|
7
|
+
|
|
8
|
+
// src/engine/improve-engine.ts
|
|
9
|
+
function improveWorld(world) {
|
|
10
|
+
const suggestions = [];
|
|
11
|
+
const report = validateWorld(world);
|
|
12
|
+
addValidationSuggestions(report.findings, suggestions);
|
|
13
|
+
analyzeRuleBalance(world, suggestions);
|
|
14
|
+
analyzeStateCoverage(world, suggestions);
|
|
15
|
+
analyzeGateCoverage(world, suggestions);
|
|
16
|
+
analyzeAssumptions(world, suggestions);
|
|
17
|
+
analyzeSimulationDynamics(world, suggestions);
|
|
18
|
+
analyzeCompleteness(world, suggestions);
|
|
19
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20
|
+
const unique = suggestions.filter((s) => {
|
|
21
|
+
if (seen.has(s.id)) return false;
|
|
22
|
+
seen.add(s.id);
|
|
23
|
+
return true;
|
|
24
|
+
});
|
|
25
|
+
const priorityOrder = {
|
|
26
|
+
critical: 0,
|
|
27
|
+
high: 1,
|
|
28
|
+
medium: 2,
|
|
29
|
+
low: 3
|
|
30
|
+
};
|
|
31
|
+
unique.sort((a, b) => priorityOrder[a.priority] - priorityOrder[b.priority]);
|
|
32
|
+
const score = computeHealthScore(world, unique);
|
|
33
|
+
return {
|
|
34
|
+
worldId: world.world.world_id,
|
|
35
|
+
worldName: world.world.name,
|
|
36
|
+
score,
|
|
37
|
+
suggestions: unique,
|
|
38
|
+
stats: {
|
|
39
|
+
critical: unique.filter((s) => s.priority === "critical").length,
|
|
40
|
+
high: unique.filter((s) => s.priority === "high").length,
|
|
41
|
+
medium: unique.filter((s) => s.priority === "medium").length,
|
|
42
|
+
low: unique.filter((s) => s.priority === "low").length
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function addValidationSuggestions(findings, suggestions) {
|
|
47
|
+
for (const f of findings) {
|
|
48
|
+
if (f.severity === "info") continue;
|
|
49
|
+
const priority = f.severity === "error" ? "critical" : "high";
|
|
50
|
+
const category = f.severity === "error" ? "fix" : "structure";
|
|
51
|
+
suggestions.push({
|
|
52
|
+
id: `validate-${f.id}`,
|
|
53
|
+
priority,
|
|
54
|
+
category,
|
|
55
|
+
title: f.message,
|
|
56
|
+
description: f.message,
|
|
57
|
+
action: f.suggestion ?? `Review ${f.affectedBlocks.join(", ")}`,
|
|
58
|
+
affectedFiles: f.affectedBlocks
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function analyzeRuleBalance(world, suggestions) {
|
|
63
|
+
if (!world.rules || world.rules.length === 0) return;
|
|
64
|
+
const structural = world.rules.filter((r) => r.severity === "structural");
|
|
65
|
+
const degradation = world.rules.filter((r) => r.severity === "degradation");
|
|
66
|
+
const advantage = world.rules.filter((r) => r.severity === "advantage");
|
|
67
|
+
if (structural.length === 0) {
|
|
68
|
+
suggestions.push({
|
|
69
|
+
id: "no-structural-rules",
|
|
70
|
+
priority: "high",
|
|
71
|
+
category: "balance",
|
|
72
|
+
title: "No structural rules",
|
|
73
|
+
description: "All rules are degradation or advantage. Structural rules define the core mechanics that hold the world together.",
|
|
74
|
+
action: "Add at least one structural-severity rule that enforces a fundamental world constraint.",
|
|
75
|
+
affectedFiles: ["rules/"]
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
if (advantage.length === 0 && world.rules.length >= 3) {
|
|
79
|
+
suggestions.push({
|
|
80
|
+
id: "no-advantage-rules",
|
|
81
|
+
priority: "medium",
|
|
82
|
+
category: "balance",
|
|
83
|
+
title: "No advantage rules",
|
|
84
|
+
description: "All rules are negative (structural or degradation). Adding advantage rules creates positive feedback loops.",
|
|
85
|
+
action: 'Add a rule with severity "advantage" that rewards desirable state.',
|
|
86
|
+
affectedFiles: ["rules/"]
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
if (degradation.length === 0 && world.rules.length >= 3) {
|
|
90
|
+
suggestions.push({
|
|
91
|
+
id: "no-degradation-rules",
|
|
92
|
+
priority: "medium",
|
|
93
|
+
category: "balance",
|
|
94
|
+
title: "No degradation rules",
|
|
95
|
+
description: "No rules model gradual decline. Degradation rules create realistic tension.",
|
|
96
|
+
action: 'Add a rule with severity "degradation" that models gradual state decline.',
|
|
97
|
+
affectedFiles: ["rules/"]
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
const missingTranslation = world.rules.filter(
|
|
101
|
+
(r) => !r.causal_translation?.trigger_text && !r.causal_translation?.effect_text
|
|
102
|
+
);
|
|
103
|
+
if (missingTranslation.length > 0 && missingTranslation.length <= 5) {
|
|
104
|
+
suggestions.push({
|
|
105
|
+
id: "missing-causal-translations",
|
|
106
|
+
priority: "low",
|
|
107
|
+
category: "completeness",
|
|
108
|
+
title: `${missingTranslation.length} rule(s) missing causal translations`,
|
|
109
|
+
description: "Causal translations provide human-readable narratives for rules. They improve explain output.",
|
|
110
|
+
action: `Add causal_translation to: ${missingTranslation.map((r) => r.id).join(", ")}`,
|
|
111
|
+
affectedFiles: ["rules/"]
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function analyzeStateCoverage(world, suggestions) {
|
|
116
|
+
if (!world.stateSchema?.variables || !world.rules) return;
|
|
117
|
+
const variables = Object.keys(world.stateSchema.variables);
|
|
118
|
+
const ruleTargets = /* @__PURE__ */ new Set();
|
|
119
|
+
const ruleTriggers = /* @__PURE__ */ new Set();
|
|
120
|
+
for (const rule of world.rules) {
|
|
121
|
+
for (const t of rule.triggers) {
|
|
122
|
+
if (t.source === "state") ruleTriggers.add(t.field);
|
|
123
|
+
}
|
|
124
|
+
for (const e of rule.effects ?? []) {
|
|
125
|
+
ruleTargets.add(e.target);
|
|
126
|
+
}
|
|
127
|
+
for (const ce of rule.effects_conditional ?? []) {
|
|
128
|
+
for (const e of ce.effects) {
|
|
129
|
+
ruleTargets.add(e.target);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
const writeOnly = variables.filter((v) => ruleTargets.has(v) && !ruleTriggers.has(v));
|
|
134
|
+
if (writeOnly.length > 0) {
|
|
135
|
+
suggestions.push({
|
|
136
|
+
id: "write-only-variables",
|
|
137
|
+
priority: "medium",
|
|
138
|
+
category: "structure",
|
|
139
|
+
title: `${writeOnly.length} write-only variable(s)`,
|
|
140
|
+
description: `These variables are modified by rules but never trigger any rule: ${writeOnly.join(", ")}. They may be dead-end state.`,
|
|
141
|
+
action: "Add rules that trigger on these variables to create feedback loops.",
|
|
142
|
+
affectedFiles: ["rules/", "state-schema.json"]
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
const readOnly = variables.filter((v) => ruleTriggers.has(v) && !ruleTargets.has(v));
|
|
146
|
+
if (readOnly.length > 0 && readOnly.length <= 3) {
|
|
147
|
+
suggestions.push({
|
|
148
|
+
id: "read-only-variables",
|
|
149
|
+
priority: "low",
|
|
150
|
+
category: "structure",
|
|
151
|
+
title: `${readOnly.length} input-only variable(s)`,
|
|
152
|
+
description: `These variables trigger rules but are never modified: ${readOnly.join(", ")}. They act as fixed inputs.`,
|
|
153
|
+
action: "This is fine for configuration inputs. If they should evolve, add rules that target them.",
|
|
154
|
+
affectedFiles: ["state-schema.json"]
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
function analyzeGateCoverage(world, suggestions) {
|
|
159
|
+
const gates = world.gates?.viability_classification ?? [];
|
|
160
|
+
if (gates.length === 0) return;
|
|
161
|
+
const statuses = new Set(gates.map((g) => g.status));
|
|
162
|
+
const standard = ["THRIVING", "STABLE", "COMPRESSED", "CRITICAL", "MODEL_COLLAPSES"];
|
|
163
|
+
const missing = standard.filter((s) => !statuses.has(s));
|
|
164
|
+
if (missing.length > 0 && missing.length <= 2) {
|
|
165
|
+
suggestions.push({
|
|
166
|
+
id: "incomplete-viability-gates",
|
|
167
|
+
priority: "medium",
|
|
168
|
+
category: "structure",
|
|
169
|
+
title: `Missing viability level(s): ${missing.join(", ")}`,
|
|
170
|
+
description: "A complete viability ladder gives finer-grained status classification.",
|
|
171
|
+
action: `Add gates for: ${missing.join(", ")}`,
|
|
172
|
+
affectedFiles: ["gates.json"]
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
function analyzeAssumptions(world, suggestions) {
|
|
177
|
+
const profiles = Object.keys(world.assumptions?.profiles ?? {});
|
|
178
|
+
if (profiles.length === 1) {
|
|
179
|
+
suggestions.push({
|
|
180
|
+
id: "single-assumption-profile",
|
|
181
|
+
priority: "medium",
|
|
182
|
+
category: "completeness",
|
|
183
|
+
title: "Only one assumption profile",
|
|
184
|
+
description: "A single profile means no scenario comparison. Add an alternative profile to enable what-if analysis.",
|
|
185
|
+
action: "Add a second profile with different parameter values to assumptions.json.",
|
|
186
|
+
affectedFiles: ["assumptions.json"]
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function analyzeSimulationDynamics(world, suggestions) {
|
|
191
|
+
if (!world.rules || world.rules.length === 0) return;
|
|
192
|
+
if (!world.stateSchema?.variables || Object.keys(world.stateSchema.variables).length === 0) return;
|
|
193
|
+
try {
|
|
194
|
+
const result = simulateWorld(world, { steps: 1 });
|
|
195
|
+
const step = result.steps[0];
|
|
196
|
+
if (step && step.rulesFired === 0) {
|
|
197
|
+
suggestions.push({
|
|
198
|
+
id: "no-rules-fire-default",
|
|
199
|
+
priority: "high",
|
|
200
|
+
category: "balance",
|
|
201
|
+
title: "No rules fire with default state",
|
|
202
|
+
description: "With all variables at their defaults, zero rules trigger. The world is inert until state changes.",
|
|
203
|
+
action: "Adjust rule thresholds or state defaults so at least some rules fire in the baseline scenario.",
|
|
204
|
+
affectedFiles: ["rules/", "state-schema.json"]
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
if (result.collapsed && result.collapseStep === 1) {
|
|
208
|
+
suggestions.push({
|
|
209
|
+
id: "immediate-collapse",
|
|
210
|
+
priority: "critical",
|
|
211
|
+
category: "balance",
|
|
212
|
+
title: "World collapses on first step",
|
|
213
|
+
description: `Rule "${result.collapseRule}" triggers collapse immediately with default state. The world cannot sustain itself.`,
|
|
214
|
+
action: "Adjust collapse thresholds or state defaults to prevent immediate collapse.",
|
|
215
|
+
affectedFiles: ["rules/", "state-schema.json"]
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
if (!result.collapsed) {
|
|
219
|
+
const multiStep = simulateWorld(world, { steps: 5 });
|
|
220
|
+
if (multiStep.collapsed) {
|
|
221
|
+
suggestions.push({
|
|
222
|
+
id: "eventual-collapse",
|
|
223
|
+
priority: "high",
|
|
224
|
+
category: "balance",
|
|
225
|
+
title: `World collapses by step ${multiStep.collapseStep}`,
|
|
226
|
+
description: `Starting from defaults, the world collapses after ${multiStep.collapseStep} steps. Consider adding stabilizing advantage rules.`,
|
|
227
|
+
action: "Add advantage rules or adjust degradation rates to allow sustainable states.",
|
|
228
|
+
affectedFiles: ["rules/"]
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
} catch {
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
function analyzeCompleteness(world, suggestions) {
|
|
236
|
+
if (!world.guards) {
|
|
237
|
+
suggestions.push({
|
|
238
|
+
id: "add-guards",
|
|
239
|
+
priority: "low",
|
|
240
|
+
category: "completeness",
|
|
241
|
+
title: "No guards defined",
|
|
242
|
+
description: "Guards enable runtime enforcement in Action Space. Without them, the world has no runtime protection.",
|
|
243
|
+
action: "Add guards.json with structural guards backing each invariant.",
|
|
244
|
+
affectedFiles: ["guards.json"]
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
if (!world.roles) {
|
|
248
|
+
suggestions.push({
|
|
249
|
+
id: "add-roles",
|
|
250
|
+
priority: "low",
|
|
251
|
+
category: "completeness",
|
|
252
|
+
title: "No roles defined",
|
|
253
|
+
description: "Roles enable multi-agent governance with different permission levels.",
|
|
254
|
+
action: "Add roles.json with at least an observer and steward role.",
|
|
255
|
+
affectedFiles: ["roles.json"]
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
if (!world.kernel) {
|
|
259
|
+
suggestions.push({
|
|
260
|
+
id: "add-kernel",
|
|
261
|
+
priority: "low",
|
|
262
|
+
category: "completeness",
|
|
263
|
+
title: "No kernel configuration",
|
|
264
|
+
description: "A kernel config provides Thinking Space governance with forbidden patterns and response vocabulary.",
|
|
265
|
+
action: "Add kernel.json with input/output boundaries.",
|
|
266
|
+
affectedFiles: ["kernel.json"]
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
const outcomes = world.outcomes?.computed_outcomes ?? [];
|
|
270
|
+
if (outcomes.length > 0 && !outcomes.some((o) => o.primary)) {
|
|
271
|
+
suggestions.push({
|
|
272
|
+
id: "no-primary-outcome",
|
|
273
|
+
priority: "medium",
|
|
274
|
+
category: "structure",
|
|
275
|
+
title: "No primary outcome defined",
|
|
276
|
+
description: "Marking one outcome as primary helps tools identify the main metric to display.",
|
|
277
|
+
action: "Set primary: true on the most important computed outcome.",
|
|
278
|
+
affectedFiles: ["outcomes.json"]
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
function computeHealthScore(world, suggestions) {
|
|
283
|
+
let score = 100;
|
|
284
|
+
for (const s of suggestions) {
|
|
285
|
+
switch (s.priority) {
|
|
286
|
+
case "critical":
|
|
287
|
+
score -= 15;
|
|
288
|
+
break;
|
|
289
|
+
case "high":
|
|
290
|
+
score -= 5;
|
|
291
|
+
break;
|
|
292
|
+
case "medium":
|
|
293
|
+
score -= 2;
|
|
294
|
+
break;
|
|
295
|
+
case "low":
|
|
296
|
+
score -= 1;
|
|
297
|
+
break;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return Math.max(0, Math.min(100, score));
|
|
301
|
+
}
|
|
302
|
+
function renderImproveText(report) {
|
|
303
|
+
const lines = [];
|
|
304
|
+
lines.push(`IMPROVE: ${report.worldName}`);
|
|
305
|
+
lines.push(`Health Score: ${report.score}/100`);
|
|
306
|
+
lines.push("");
|
|
307
|
+
if (report.suggestions.length === 0) {
|
|
308
|
+
lines.push("No suggestions \u2014 this world is in great shape.");
|
|
309
|
+
return lines.join("\n");
|
|
310
|
+
}
|
|
311
|
+
const groups = [
|
|
312
|
+
["CRITICAL (must fix)", "critical", "x"],
|
|
313
|
+
["HIGH PRIORITY", "high", "!"],
|
|
314
|
+
["SUGGESTIONS", "medium", "-"],
|
|
315
|
+
["NICE TO HAVE", "low", "."]
|
|
316
|
+
];
|
|
317
|
+
for (const [header, priority, icon] of groups) {
|
|
318
|
+
const items = report.suggestions.filter((s) => s.priority === priority);
|
|
319
|
+
if (items.length === 0) continue;
|
|
320
|
+
lines.push(header);
|
|
321
|
+
for (const s of items) {
|
|
322
|
+
lines.push(` ${icon} ${s.title}`);
|
|
323
|
+
lines.push(` Action: ${s.action}`);
|
|
324
|
+
}
|
|
325
|
+
lines.push("");
|
|
326
|
+
}
|
|
327
|
+
const { stats } = report;
|
|
328
|
+
const parts = [];
|
|
329
|
+
if (stats.critical > 0) parts.push(`${stats.critical} critical`);
|
|
330
|
+
if (stats.high > 0) parts.push(`${stats.high} high`);
|
|
331
|
+
if (stats.medium > 0) parts.push(`${stats.medium} medium`);
|
|
332
|
+
if (stats.low > 0) parts.push(`${stats.low} low`);
|
|
333
|
+
lines.push(`Total: ${report.suggestions.length} suggestions (${parts.join(", ")})`);
|
|
334
|
+
return lines.join("\n");
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
export {
|
|
338
|
+
improveWorld,
|
|
339
|
+
renderImproveText
|
|
340
|
+
};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import {
|
|
2
|
+
evaluateGuard
|
|
3
|
+
} from "./chunk-W7LLXRGY.js";
|
|
4
|
+
import {
|
|
5
|
+
loadWorld
|
|
6
|
+
} from "./chunk-CTZHONLA.js";
|
|
7
|
+
|
|
8
|
+
// src/adapters/express.ts
|
|
9
|
+
function methodToCategory(method) {
|
|
10
|
+
switch (method.toUpperCase()) {
|
|
11
|
+
case "GET":
|
|
12
|
+
case "HEAD":
|
|
13
|
+
case "OPTIONS":
|
|
14
|
+
return "read";
|
|
15
|
+
case "POST":
|
|
16
|
+
case "PUT":
|
|
17
|
+
case "PATCH":
|
|
18
|
+
return "write";
|
|
19
|
+
case "DELETE":
|
|
20
|
+
return "delete";
|
|
21
|
+
default:
|
|
22
|
+
return "other";
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function defaultMapRequest(req) {
|
|
26
|
+
const method = (req.method ?? "GET").toUpperCase();
|
|
27
|
+
const path = req.path ?? req.url ?? "/";
|
|
28
|
+
return {
|
|
29
|
+
intent: `${method} ${path}`,
|
|
30
|
+
tool: "http",
|
|
31
|
+
scope: path,
|
|
32
|
+
actionCategory: methodToCategory(method),
|
|
33
|
+
direction: "input",
|
|
34
|
+
args: {
|
|
35
|
+
method,
|
|
36
|
+
path,
|
|
37
|
+
...req.params ?? {},
|
|
38
|
+
...req.query ?? {}
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function defaultOnBlock(verdict, _req, res, statusCode) {
|
|
43
|
+
const body = {
|
|
44
|
+
error: "Governance policy violation",
|
|
45
|
+
reason: verdict.reason ?? "Action not permitted",
|
|
46
|
+
ruleId: verdict.ruleId,
|
|
47
|
+
status: verdict.status
|
|
48
|
+
};
|
|
49
|
+
if (typeof res.status === "function" && typeof res.json === "function") {
|
|
50
|
+
const r = res.status(statusCode);
|
|
51
|
+
r.json(body);
|
|
52
|
+
} else if (res.send) {
|
|
53
|
+
res.statusCode = statusCode;
|
|
54
|
+
res.send(JSON.stringify(body));
|
|
55
|
+
} else if (res.end) {
|
|
56
|
+
res.statusCode = statusCode;
|
|
57
|
+
res.end();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async function createGovernanceMiddleware(worldPath, options) {
|
|
61
|
+
const world = await loadWorld(worldPath);
|
|
62
|
+
return createGovernanceMiddlewareFromWorld(world, options);
|
|
63
|
+
}
|
|
64
|
+
function createGovernanceMiddlewareFromWorld(world, options = {}) {
|
|
65
|
+
const engineOptions = {
|
|
66
|
+
trace: options.trace ?? false,
|
|
67
|
+
level: options.level
|
|
68
|
+
};
|
|
69
|
+
const mapRequest = options.mapRequest ?? defaultMapRequest;
|
|
70
|
+
const blockStatusCode = options.blockStatusCode ?? 403;
|
|
71
|
+
return async function neuroVerseGovernance(req, res, next) {
|
|
72
|
+
try {
|
|
73
|
+
const event = mapRequest(req);
|
|
74
|
+
const verdict = evaluateGuard(event, world, engineOptions);
|
|
75
|
+
options.onEvaluate?.(verdict, event, req);
|
|
76
|
+
if (verdict.status === "ALLOW") {
|
|
77
|
+
next();
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
if (verdict.status === "PAUSE") {
|
|
81
|
+
const approved = await options.onPause?.(verdict, req);
|
|
82
|
+
if (approved) {
|
|
83
|
+
next();
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (options.onBlock) {
|
|
88
|
+
options.onBlock(verdict, req, res);
|
|
89
|
+
} else {
|
|
90
|
+
defaultOnBlock(verdict, req, res, blockStatusCode);
|
|
91
|
+
}
|
|
92
|
+
} catch (err) {
|
|
93
|
+
next(err);
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export {
|
|
99
|
+
createGovernanceMiddleware,
|
|
100
|
+
createGovernanceMiddlewareFromWorld
|
|
101
|
+
};
|