@neuroverseos/nv-sim 0.1.4 → 0.1.5
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/README.md +346 -68
- package/dist/adapters/mirofish.js +461 -0
- package/dist/adapters/scienceclaw.js +750 -0
- package/dist/assets/index-B64NuIXu.css +1 -0
- package/dist/assets/index-DbzSnYxr.js +532 -0
- package/dist/assets/{reportEngine-BfteK4MN.js → reportEngine-DKWTrP6-.js} +1 -1
- package/dist/components/ConstraintsPanel.js +11 -0
- package/dist/components/StakeholderBuilder.js +32 -0
- package/dist/components/ui/badge.js +24 -0
- package/dist/components/ui/button.js +70 -0
- package/dist/components/ui/card.js +57 -0
- package/dist/components/ui/input.js +44 -0
- package/dist/components/ui/label.js +45 -0
- package/dist/components/ui/select.js +70 -0
- package/dist/engine/aiProvider.js +427 -2
- package/dist/engine/auditTrace.js +352 -0
- package/dist/engine/behavioralAnalysis.js +605 -0
- package/dist/engine/cli.js +1087 -13
- package/dist/engine/dynamicsGovernance.js +588 -0
- package/dist/engine/fullGovernedLoop.js +367 -0
- package/dist/engine/governedSimulation.js +77 -6
- package/dist/engine/index.js +41 -1
- package/dist/engine/liveVisualizer.js +2787 -360
- package/dist/engine/metrics/science.metrics.js +335 -0
- package/dist/engine/narrativeInjection.js +55 -0
- package/dist/engine/policyEnforcement.js +1611 -0
- package/dist/engine/policyEngine.js +799 -0
- package/dist/engine/primeRadiant.js +540 -0
- package/dist/engine/scenarioCapsule.js +56 -0
- package/dist/engine/scenarioComparison.js +463 -0
- package/dist/engine/scenarioLibrary.js +17 -0
- package/dist/engine/swarmSimulation.js +54 -1
- package/dist/engine/worldComparison.js +164 -0
- package/dist/engine/worldStorage.js +232 -0
- package/dist/index.html +2 -2
- package/dist/lib/reasoningEngine.js +290 -0
- package/dist/lib/simulationAdapter.js +686 -0
- package/dist/lib/swarmParser.js +291 -0
- package/dist/lib/types.js +2 -0
- package/dist/lib/utils.js +8 -0
- package/dist/runtime/govern.js +473 -0
- package/dist/runtime/index.js +75 -0
- package/dist/runtime/types.js +11 -0
- package/package.json +5 -2
- package/dist/assets/index-DHKd4rcV.js +0 -338
- package/dist/assets/index-SyyA3z3U.css +0 -1
- package/dist/assets/swarmSimulation-DHDqjfMa.js +0 -1
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* NeuroVerse Governance Runtime — Core Engine
|
|
4
|
+
*
|
|
5
|
+
* The ONE function that makes NeuroVerse real:
|
|
6
|
+
*
|
|
7
|
+
* agent decides → govern() evaluates → action proceeds (or doesn't)
|
|
8
|
+
*
|
|
9
|
+
* This is NOT a simulator. This is a governance layer that sits
|
|
10
|
+
* between agent decisions and execution in ANY agent system.
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* import { govern, createGovernor } from "@neuroverseos/runtime"
|
|
14
|
+
*
|
|
15
|
+
* // One-shot:
|
|
16
|
+
* const verdict = govern(action, worldState, "Block large trades during volatility")
|
|
17
|
+
*
|
|
18
|
+
* // Reusable governor:
|
|
19
|
+
* const gov = createGovernor({ policyText: myPolicy })
|
|
20
|
+
* const verdict = gov.evaluate(action)
|
|
21
|
+
*/
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
exports.EXAMPLE_WORLD_STATES = exports.EXAMPLE_ACTIONS = void 0;
|
|
24
|
+
exports.govern = govern;
|
|
25
|
+
exports.createGovernor = createGovernor;
|
|
26
|
+
const policyEngine_1 = require("../engine/policyEngine");
|
|
27
|
+
// ============================================
|
|
28
|
+
// CORE: govern() — evaluate a single action
|
|
29
|
+
// ============================================
|
|
30
|
+
/**
|
|
31
|
+
* Evaluate a single agent action against a policy.
|
|
32
|
+
*
|
|
33
|
+
* This is the simplest way to use NeuroVerse governance.
|
|
34
|
+
* For repeated evaluations, use createGovernor() instead.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* const verdict = govern(
|
|
38
|
+
* { agentId: "fund-A", type: "trade", description: "Sell $15M in equities", magnitude: 0.8 },
|
|
39
|
+
* { volatility: 85, liquidity: 12 },
|
|
40
|
+
* "Block all large trades during extreme volatility\nHalt trading when volatility exceeds 80"
|
|
41
|
+
* )
|
|
42
|
+
*
|
|
43
|
+
* if (verdict.status === "ALLOW") execute(verdict.action)
|
|
44
|
+
*/
|
|
45
|
+
function govern(action, worldState, policyText) {
|
|
46
|
+
const governor = createGovernor({ policyText, worldState });
|
|
47
|
+
return governor.evaluate(action, worldState);
|
|
48
|
+
}
|
|
49
|
+
// ============================================
|
|
50
|
+
// FACTORY: createGovernor() — reusable instance
|
|
51
|
+
// ============================================
|
|
52
|
+
/**
|
|
53
|
+
* Create a reusable governor instance.
|
|
54
|
+
*
|
|
55
|
+
* Parse the policy once, evaluate many actions.
|
|
56
|
+
* This is the recommended way to use NeuroVerse in a simulation loop.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* const gov = createGovernor({ policyText: myPolicy })
|
|
60
|
+
*
|
|
61
|
+
* for (const agent of agents) {
|
|
62
|
+
* const action = agent.decide()
|
|
63
|
+
* const verdict = gov.evaluate(action, currentWorldState)
|
|
64
|
+
* if (verdict.action) execute(verdict.action)
|
|
65
|
+
* }
|
|
66
|
+
*
|
|
67
|
+
* console.log(gov.stats) // { totalEvaluations: 50, blocked: 12, ... }
|
|
68
|
+
*/
|
|
69
|
+
function createGovernor(config) {
|
|
70
|
+
let parsed = (0, policyEngine_1.parseRulesFromText)(config.policyText);
|
|
71
|
+
let health = (0, policyEngine_1.validatePolicy)(parsed);
|
|
72
|
+
let world = (0, policyEngine_1.policyToWorld)(parsed);
|
|
73
|
+
const sensitivity = config.sensitivity ?? 0.5;
|
|
74
|
+
const audit = config.auditTrail ?? null;
|
|
75
|
+
// Running stats
|
|
76
|
+
const stats = {
|
|
77
|
+
totalEvaluations: 0,
|
|
78
|
+
allowed: 0,
|
|
79
|
+
blocked: 0,
|
|
80
|
+
modified: 0,
|
|
81
|
+
paused: 0,
|
|
82
|
+
rulesFired: 0,
|
|
83
|
+
};
|
|
84
|
+
function evaluate(action, worldState) {
|
|
85
|
+
stats.totalEvaluations++;
|
|
86
|
+
const rulesFired = [];
|
|
87
|
+
let currentMagnitude = action.magnitude;
|
|
88
|
+
let wasModified = false;
|
|
89
|
+
// --- Evaluate action against each invariant ---
|
|
90
|
+
for (const inv of world.invariants) {
|
|
91
|
+
if (!inv.enforceable) {
|
|
92
|
+
// Advisory: log but don't block
|
|
93
|
+
rulesFired.push({
|
|
94
|
+
id: inv.id,
|
|
95
|
+
description: inv.description,
|
|
96
|
+
effect: "monitored",
|
|
97
|
+
impactReduction: 0,
|
|
98
|
+
});
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
const result = evaluateInvariant(inv, action, currentMagnitude, worldState, sensitivity);
|
|
102
|
+
if (result) {
|
|
103
|
+
rulesFired.push(result);
|
|
104
|
+
currentMagnitude = action.magnitude * (1 - result.impactReduction);
|
|
105
|
+
wasModified = true;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// --- Evaluate action against gates ---
|
|
109
|
+
for (const gate of world.gates ?? []) {
|
|
110
|
+
const result = evaluateGate(gate, action, currentMagnitude, worldState);
|
|
111
|
+
if (result) {
|
|
112
|
+
rulesFired.push(result);
|
|
113
|
+
currentMagnitude = currentMagnitude * (1 - result.impactReduction);
|
|
114
|
+
wasModified = true;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// --- Determine final verdict ---
|
|
118
|
+
stats.rulesFired += rulesFired.filter((r) => r.effect !== "monitored").length;
|
|
119
|
+
const totalReduction = 1 - (currentMagnitude / Math.max(action.magnitude, 0.001));
|
|
120
|
+
let status;
|
|
121
|
+
let reason;
|
|
122
|
+
let outputAction;
|
|
123
|
+
if (totalReduction > 0.85) {
|
|
124
|
+
// Action is essentially killed
|
|
125
|
+
status = "BLOCK";
|
|
126
|
+
reason = buildReason("blocked", action, rulesFired);
|
|
127
|
+
outputAction = null;
|
|
128
|
+
stats.blocked++;
|
|
129
|
+
}
|
|
130
|
+
else if (totalReduction > 0.5) {
|
|
131
|
+
// Action is significantly reduced — pause for review
|
|
132
|
+
status = "PAUSE";
|
|
133
|
+
reason = buildReason("paused", action, rulesFired);
|
|
134
|
+
outputAction = { ...action, magnitude: Number(currentMagnitude.toFixed(3)) };
|
|
135
|
+
stats.paused++;
|
|
136
|
+
}
|
|
137
|
+
else if (wasModified && totalReduction > 0.05) {
|
|
138
|
+
// Action was modified but still largely allowed
|
|
139
|
+
status = "MODIFY";
|
|
140
|
+
reason = buildReason("modified", action, rulesFired);
|
|
141
|
+
outputAction = { ...action, magnitude: Number(currentMagnitude.toFixed(3)) };
|
|
142
|
+
stats.modified++;
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
// Clean pass
|
|
146
|
+
status = "ALLOW";
|
|
147
|
+
reason = rulesFired.length > 0
|
|
148
|
+
? `Allowed — ${rulesFired.filter((r) => r.effect === "monitored").length} advisory rule(s) noted`
|
|
149
|
+
: "Allowed — no rules apply to this action";
|
|
150
|
+
outputAction = action;
|
|
151
|
+
stats.allowed++;
|
|
152
|
+
}
|
|
153
|
+
const verdict = {
|
|
154
|
+
status,
|
|
155
|
+
action: outputAction,
|
|
156
|
+
reason,
|
|
157
|
+
rulesFired,
|
|
158
|
+
confidence: computeConfidence(rulesFired, totalReduction),
|
|
159
|
+
timestamp: Date.now(),
|
|
160
|
+
};
|
|
161
|
+
// Persist to audit trail if configured
|
|
162
|
+
if (audit) {
|
|
163
|
+
audit.logVerdict({
|
|
164
|
+
agent: action.agentId,
|
|
165
|
+
action: action.description,
|
|
166
|
+
actionType: action.type,
|
|
167
|
+
verdict: status === "MODIFY" ? "MODIFY" : status,
|
|
168
|
+
reason,
|
|
169
|
+
confidence: verdict.confidence,
|
|
170
|
+
rulesFired: rulesFired.map((r) => ({
|
|
171
|
+
id: r.id,
|
|
172
|
+
description: r.description,
|
|
173
|
+
effect: r.effect,
|
|
174
|
+
impactReduction: r.impactReduction,
|
|
175
|
+
})),
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
return verdict;
|
|
179
|
+
}
|
|
180
|
+
function evaluateBatch(actions, worldState) {
|
|
181
|
+
return actions.map((a) => evaluate(a, worldState));
|
|
182
|
+
}
|
|
183
|
+
function updatePolicy(policyText) {
|
|
184
|
+
parsed = (0, policyEngine_1.parseRulesFromText)(policyText);
|
|
185
|
+
health = (0, policyEngine_1.validatePolicy)(parsed);
|
|
186
|
+
world = (0, policyEngine_1.policyToWorld)(parsed);
|
|
187
|
+
}
|
|
188
|
+
return {
|
|
189
|
+
evaluate,
|
|
190
|
+
evaluateBatch,
|
|
191
|
+
updatePolicy,
|
|
192
|
+
get policy() {
|
|
193
|
+
return {
|
|
194
|
+
ruleCount: parsed.summary.total,
|
|
195
|
+
enforcedCount: parsed.summary.enforced,
|
|
196
|
+
advisoryCount: parsed.summary.advisory,
|
|
197
|
+
healthScore: health.healthScore,
|
|
198
|
+
};
|
|
199
|
+
},
|
|
200
|
+
get stats() {
|
|
201
|
+
return { ...stats };
|
|
202
|
+
},
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
// ============================================
|
|
206
|
+
// INVARIANT EVALUATION (single rule vs action)
|
|
207
|
+
// ============================================
|
|
208
|
+
function evaluateInvariant(inv, action, currentMagnitude, worldState, sensitivity) {
|
|
209
|
+
const desc = inv.description.toLowerCase();
|
|
210
|
+
const actionDesc = action.description.toLowerCase();
|
|
211
|
+
const actionType = action.type.toLowerCase();
|
|
212
|
+
// Sensitivity adjusts thresholds: 0 = lenient, 1 = strict
|
|
213
|
+
const threshold = 0.6 - sensitivity * 0.3; // Range: 0.3 (strict) to 0.6 (lenient)
|
|
214
|
+
// --- BLOCK/PROHIBIT patterns ---
|
|
215
|
+
if (matchesPattern(desc, ["block", "prohibit", "prevent", "forbid", "ban", "stop", "halt"])) {
|
|
216
|
+
const actionTerms = extractActionTerms(desc, ["block", "prohibit", "prevent", "forbid", "ban", "stop", "halt"]);
|
|
217
|
+
const matches = actionTerms.some((term) => actionDesc.includes(term) || actionType.includes(term));
|
|
218
|
+
const isExtreme = action.magnitude > threshold;
|
|
219
|
+
if (matches || isExtreme) {
|
|
220
|
+
return {
|
|
221
|
+
id: inv.id,
|
|
222
|
+
description: inv.description,
|
|
223
|
+
effect: "blocked",
|
|
224
|
+
impactReduction: 0.85 + sensitivity * 0.1, // 85–95% reduction
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
// --- CIRCUIT BREAKER / PANIC patterns ---
|
|
229
|
+
if (matchesPattern(desc, ["panic", "cascade", "contagion", "crash", "circuit", "emergency", "runaway"])) {
|
|
230
|
+
// Check if world state indicates crisis conditions
|
|
231
|
+
const inCrisis = worldState
|
|
232
|
+
? isWorldInCrisis(worldState)
|
|
233
|
+
: action.magnitude > 0.6;
|
|
234
|
+
if (inCrisis && action.magnitude > threshold * 0.8) {
|
|
235
|
+
return {
|
|
236
|
+
id: inv.id,
|
|
237
|
+
description: inv.description,
|
|
238
|
+
effect: "blocked",
|
|
239
|
+
impactReduction: 0.7 + sensitivity * 0.2, // 70–90% reduction
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
// --- SLOW/DAMPEN patterns ---
|
|
244
|
+
if (matchesPattern(desc, ["slow", "cool", "gradual", "dampen", "reduce volatility", "moderate"])) {
|
|
245
|
+
if (action.magnitude > threshold) {
|
|
246
|
+
return {
|
|
247
|
+
id: inv.id,
|
|
248
|
+
description: inv.description,
|
|
249
|
+
effect: "dampened",
|
|
250
|
+
impactReduction: 0.35 + sensitivity * 0.15, // 35–50% reduction
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
// --- FLOOR/MINIMUM patterns ---
|
|
255
|
+
if (matchesPattern(desc, ["floor", "maintain", "minimum", "at least", "no less"])) {
|
|
256
|
+
// Check if action would violate a floor
|
|
257
|
+
const wouldViolateFloor = action.magnitude > 0.4 && actionMatchesVariable(desc, actionDesc);
|
|
258
|
+
if (wouldViolateFloor) {
|
|
259
|
+
return {
|
|
260
|
+
id: inv.id,
|
|
261
|
+
description: inv.description,
|
|
262
|
+
effect: "capped",
|
|
263
|
+
impactReduction: Math.min(0.5, action.magnitude - 0.3), // Cap to safe level
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
// --- LIMIT/CAP/LEVERAGE patterns ---
|
|
268
|
+
if (matchesPattern(desc, ["leverage", "limit", "cap", "restrict", "maximum", "no more", "ceiling"])) {
|
|
269
|
+
if (action.magnitude > threshold + 0.1) {
|
|
270
|
+
return {
|
|
271
|
+
id: inv.id,
|
|
272
|
+
description: inv.description,
|
|
273
|
+
effect: "capped",
|
|
274
|
+
impactReduction: Math.min(0.4, action.magnitude - threshold), // Reduce excess above threshold
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
// --- REBALANCE/EQUILIBRIUM patterns ---
|
|
279
|
+
if (matchesPattern(desc, ["rebalance", "equilibrium", "balance", "correlat", "diversif"])) {
|
|
280
|
+
if (action.magnitude > 0.5) {
|
|
281
|
+
return {
|
|
282
|
+
id: inv.id,
|
|
283
|
+
description: inv.description,
|
|
284
|
+
effect: "rebalanced",
|
|
285
|
+
impactReduction: 0.3 * sensitivity, // Gentle pull toward center
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
// --- TRANSPARENCY/REPORTING patterns ---
|
|
290
|
+
if (matchesPattern(desc, ["transparency", "report", "monitor", "audit", "disclose", "accountab"])) {
|
|
291
|
+
// Transparency rules don't block — they just observe
|
|
292
|
+
if (action.magnitude > 0.3) {
|
|
293
|
+
return {
|
|
294
|
+
id: inv.id,
|
|
295
|
+
description: inv.description,
|
|
296
|
+
effect: "monitored",
|
|
297
|
+
impactReduction: 0, // No reduction, just logging
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
// ============================================
|
|
304
|
+
// GATE EVALUATION (threshold checks)
|
|
305
|
+
// ============================================
|
|
306
|
+
function evaluateGate(gate, action, currentMagnitude, worldState) {
|
|
307
|
+
if (gate.severity === "critical") {
|
|
308
|
+
// Critical gates act as hard circuit breakers
|
|
309
|
+
const inDanger = worldState
|
|
310
|
+
? isWorldInCrisis(worldState)
|
|
311
|
+
: currentMagnitude > 0.5;
|
|
312
|
+
if (inDanger && action.magnitude > 0.3) {
|
|
313
|
+
return {
|
|
314
|
+
id: gate.id,
|
|
315
|
+
description: gate.label,
|
|
316
|
+
effect: "blocked",
|
|
317
|
+
impactReduction: 0.4, // Flatten all actions during crisis
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
if (gate.severity === "warning") {
|
|
322
|
+
// Warning gates add caution
|
|
323
|
+
if (action.magnitude > 0.5) {
|
|
324
|
+
return {
|
|
325
|
+
id: gate.id,
|
|
326
|
+
description: gate.label,
|
|
327
|
+
effect: "dampened",
|
|
328
|
+
impactReduction: 0.2, // Mild reduction
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
return null;
|
|
333
|
+
}
|
|
334
|
+
// ============================================
|
|
335
|
+
// HELPERS
|
|
336
|
+
// ============================================
|
|
337
|
+
function matchesPattern(text, patterns) {
|
|
338
|
+
return patterns.some((p) => text.includes(p));
|
|
339
|
+
}
|
|
340
|
+
function extractActionTerms(ruleDesc, removePatterns) {
|
|
341
|
+
let cleaned = ruleDesc;
|
|
342
|
+
for (const p of removePatterns) {
|
|
343
|
+
cleaned = cleaned.replace(new RegExp(`\\b${p}\\b`, "g"), "");
|
|
344
|
+
}
|
|
345
|
+
return cleaned
|
|
346
|
+
.split(/\s+/)
|
|
347
|
+
.filter((t) => t.length > 2)
|
|
348
|
+
.map((t) => t.replace(/[^a-z]/g, ""))
|
|
349
|
+
.filter((t) => t.length > 2);
|
|
350
|
+
}
|
|
351
|
+
function actionMatchesVariable(ruleDesc, actionDesc) {
|
|
352
|
+
const ruleTerms = ruleDesc.split(/\s+/).filter((t) => t.length > 3);
|
|
353
|
+
return ruleTerms.some((t) => actionDesc.includes(t));
|
|
354
|
+
}
|
|
355
|
+
function isWorldInCrisis(ws) {
|
|
356
|
+
const vol = ws["volatility"] ?? ws["volatility_index"];
|
|
357
|
+
const liq = ws["liquidity"] ?? ws["liquidity_index"];
|
|
358
|
+
if (typeof vol === "number" && vol > 70)
|
|
359
|
+
return true;
|
|
360
|
+
if (typeof liq === "number" && liq < 20)
|
|
361
|
+
return true;
|
|
362
|
+
if (ws["sentiment"] === "panic" || ws["contagion_spread"] === "systemic")
|
|
363
|
+
return true;
|
|
364
|
+
return false;
|
|
365
|
+
}
|
|
366
|
+
function computeConfidence(rulesFired, totalReduction) {
|
|
367
|
+
if (rulesFired.length === 0)
|
|
368
|
+
return 0.95; // High confidence in "no rules apply"
|
|
369
|
+
const enforcedCount = rulesFired.filter((r) => r.effect !== "monitored").length;
|
|
370
|
+
// More rules firing = higher confidence in verdict
|
|
371
|
+
return Math.min(0.99, 0.6 + enforcedCount * 0.1 + totalReduction * 0.2);
|
|
372
|
+
}
|
|
373
|
+
function buildReason(type, action, rulesFired) {
|
|
374
|
+
const enforced = rulesFired.filter((r) => r.effect !== "monitored");
|
|
375
|
+
if (enforced.length === 0) {
|
|
376
|
+
return `${capitalize(type)} due to aggregate policy thresholds`;
|
|
377
|
+
}
|
|
378
|
+
const primary = enforced[0];
|
|
379
|
+
const others = enforced.length > 1 ? ` (+${enforced.length - 1} more)` : "";
|
|
380
|
+
switch (type) {
|
|
381
|
+
case "blocked":
|
|
382
|
+
return `Blocked by "${primary.description}"${others} — action "${action.description}" violates governance constraints`;
|
|
383
|
+
case "paused":
|
|
384
|
+
return `Paused by "${primary.description}"${others} — action "${action.description}" requires review`;
|
|
385
|
+
case "modified":
|
|
386
|
+
return `Modified by "${primary.description}"${others} — magnitude reduced from ${action.magnitude.toFixed(2)} to stay within policy limits`;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
function capitalize(s) {
|
|
390
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
391
|
+
}
|
|
392
|
+
// ============================================
|
|
393
|
+
// EXAMPLE ACTIONS — for playground / demo
|
|
394
|
+
// ============================================
|
|
395
|
+
/**
|
|
396
|
+
* Pre-built example actions for testing governance.
|
|
397
|
+
* These map to common scenarios users would simulate.
|
|
398
|
+
*/
|
|
399
|
+
exports.EXAMPLE_ACTIONS = [
|
|
400
|
+
{
|
|
401
|
+
agentId: "hedge-fund-alpha",
|
|
402
|
+
type: "trade",
|
|
403
|
+
description: "Sell $20M in equities during market downturn",
|
|
404
|
+
magnitude: 0.85,
|
|
405
|
+
context: { asset: "equities", amount: 20_000_000, direction: "sell" },
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
agentId: "algo-trader-7",
|
|
409
|
+
type: "trade",
|
|
410
|
+
description: "Execute high-frequency arbitrage strategy",
|
|
411
|
+
magnitude: 0.6,
|
|
412
|
+
context: { strategy: "arbitrage", automated: true },
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
agentId: "pension-fund",
|
|
416
|
+
type: "trade",
|
|
417
|
+
description: "Buy $5M in government bonds",
|
|
418
|
+
magnitude: 0.25,
|
|
419
|
+
context: { asset: "bonds", amount: 5_000_000, direction: "buy" },
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
agentId: "market-maker-3",
|
|
423
|
+
type: "withdrawal",
|
|
424
|
+
description: "Withdraw liquidity from the market",
|
|
425
|
+
magnitude: 0.7,
|
|
426
|
+
context: { type: "liquidity_withdrawal" },
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
agentId: "retail-coalition",
|
|
430
|
+
type: "trade",
|
|
431
|
+
description: "Coordinated buy of meme stock",
|
|
432
|
+
magnitude: 0.55,
|
|
433
|
+
context: { coordinated: true, participants: 1200 },
|
|
434
|
+
},
|
|
435
|
+
{
|
|
436
|
+
agentId: "quant-fund-beta",
|
|
437
|
+
type: "leverage",
|
|
438
|
+
description: "Increase leverage to 8x on volatile positions",
|
|
439
|
+
magnitude: 0.9,
|
|
440
|
+
context: { leverage: 8, current_leverage: 3 },
|
|
441
|
+
},
|
|
442
|
+
{
|
|
443
|
+
agentId: "central-bank",
|
|
444
|
+
type: "intervention",
|
|
445
|
+
description: "Inject emergency liquidity into the system",
|
|
446
|
+
magnitude: 0.4,
|
|
447
|
+
context: { type: "liquidity_injection" },
|
|
448
|
+
},
|
|
449
|
+
{
|
|
450
|
+
agentId: "insurance-pool",
|
|
451
|
+
type: "trade",
|
|
452
|
+
description: "Rebalance portfolio under normal conditions",
|
|
453
|
+
magnitude: 0.15,
|
|
454
|
+
context: { type: "rebalance", routine: true },
|
|
455
|
+
},
|
|
456
|
+
];
|
|
457
|
+
/**
|
|
458
|
+
* Pre-built world state snapshots for testing.
|
|
459
|
+
*/
|
|
460
|
+
exports.EXAMPLE_WORLD_STATES = {
|
|
461
|
+
calm: {
|
|
462
|
+
label: "Calm Market",
|
|
463
|
+
state: { volatility: 25, liquidity: 70, leverage: 2, sentiment: "stable", contagion_spread: "contained" },
|
|
464
|
+
},
|
|
465
|
+
stressed: {
|
|
466
|
+
label: "Stressed Market",
|
|
467
|
+
state: { volatility: 55, liquidity: 35, leverage: 5, sentiment: "anxious", contagion_spread: "spreading" },
|
|
468
|
+
},
|
|
469
|
+
crisis: {
|
|
470
|
+
label: "Full Crisis",
|
|
471
|
+
state: { volatility: 88, liquidity: 8, leverage: 12, sentiment: "panic", contagion_spread: "systemic" },
|
|
472
|
+
},
|
|
473
|
+
};
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @neuroverseos/runtime — Governance Layer for Agent Systems
|
|
4
|
+
*
|
|
5
|
+
* NeuroVerse plugs into any agent system and enforces what
|
|
6
|
+
* actions are allowed before they execute.
|
|
7
|
+
*
|
|
8
|
+
* Quick start:
|
|
9
|
+
* import { govern } from "@neuroverseos/runtime"
|
|
10
|
+
*
|
|
11
|
+
* const verdict = govern(action, worldState, policyText)
|
|
12
|
+
* if (verdict.status === "ALLOW") execute(verdict.action)
|
|
13
|
+
*
|
|
14
|
+
* Reusable governor:
|
|
15
|
+
* import { createGovernor } from "@neuroverseos/runtime"
|
|
16
|
+
*
|
|
17
|
+
* const gov = createGovernor({ policyText: myPolicy })
|
|
18
|
+
* for (const agent of agents) {
|
|
19
|
+
* const verdict = gov.evaluate(agent.decide(), worldState)
|
|
20
|
+
* if (verdict.action) execute(verdict.action)
|
|
21
|
+
* }
|
|
22
|
+
*
|
|
23
|
+
* Dynamics governance (system-level, per-round):
|
|
24
|
+
* import { governDynamics, createDynamicsGovernor } from "@neuroverseos/runtime"
|
|
25
|
+
*
|
|
26
|
+
* const dynamics = createDynamicsGovernor(policyText)
|
|
27
|
+
* for (const round of simulation) {
|
|
28
|
+
* // ... agents act, govern() filters actions ...
|
|
29
|
+
* const result = dynamics.governRound(reactions, systemState, round)
|
|
30
|
+
* }
|
|
31
|
+
*
|
|
32
|
+
* Prime Radiant (unified platform):
|
|
33
|
+
* import { createPrimeRadiant } from "@neuroverseos/runtime"
|
|
34
|
+
*
|
|
35
|
+
* const radiant = createPrimeRadiant({ scenario, policyText })
|
|
36
|
+
* const world = radiant.buildWorld()
|
|
37
|
+
* const sim = await radiant.runGovernedSimulation()
|
|
38
|
+
* const decision = await radiant.compareOptions(options)
|
|
39
|
+
*/
|
|
40
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
+
exports.createMiroFishWrapper = exports.generateDemoInvestigation = exports.createScienceClawAdapter = exports.interpretScienceState = exports.SCIENCE_INITIAL_STATE = exports.SCIENCE_POLICY_TEXT = exports.SCIENCE_METRICS = exports.PRIME_RADIANT_PRESETS = exports.createPrimeRadiant = exports.DEFAULT_METRICS = exports.runScenarioMatrix = exports.runFullGovernedSimulation = exports.createDynamicsGovernor = exports.governDynamics = exports.EXAMPLE_WORLD_STATES = exports.EXAMPLE_ACTIONS = exports.createGovernor = exports.govern = void 0;
|
|
42
|
+
// Core runtime — Layer A: action governance
|
|
43
|
+
var govern_1 = require("./govern");
|
|
44
|
+
Object.defineProperty(exports, "govern", { enumerable: true, get: function () { return govern_1.govern; } });
|
|
45
|
+
Object.defineProperty(exports, "createGovernor", { enumerable: true, get: function () { return govern_1.createGovernor; } });
|
|
46
|
+
Object.defineProperty(exports, "EXAMPLE_ACTIONS", { enumerable: true, get: function () { return govern_1.EXAMPLE_ACTIONS; } });
|
|
47
|
+
Object.defineProperty(exports, "EXAMPLE_WORLD_STATES", { enumerable: true, get: function () { return govern_1.EXAMPLE_WORLD_STATES; } });
|
|
48
|
+
// Layer B: dynamics governance
|
|
49
|
+
var dynamicsGovernance_1 = require("../engine/dynamicsGovernance");
|
|
50
|
+
Object.defineProperty(exports, "governDynamics", { enumerable: true, get: function () { return dynamicsGovernance_1.governDynamics; } });
|
|
51
|
+
Object.defineProperty(exports, "createDynamicsGovernor", { enumerable: true, get: function () { return dynamicsGovernance_1.createDynamicsGovernor; } });
|
|
52
|
+
// Full governed simulation loop
|
|
53
|
+
var fullGovernedLoop_1 = require("../engine/fullGovernedLoop");
|
|
54
|
+
Object.defineProperty(exports, "runFullGovernedSimulation", { enumerable: true, get: function () { return fullGovernedLoop_1.runFullGovernedSimulation; } });
|
|
55
|
+
// Multi-scenario comparison & decision intelligence
|
|
56
|
+
var scenarioComparison_1 = require("../engine/scenarioComparison");
|
|
57
|
+
Object.defineProperty(exports, "runScenarioMatrix", { enumerable: true, get: function () { return scenarioComparison_1.runScenarioMatrix; } });
|
|
58
|
+
Object.defineProperty(exports, "DEFAULT_METRICS", { enumerable: true, get: function () { return scenarioComparison_1.DEFAULT_METRICS; } });
|
|
59
|
+
// Prime Radiant — unified platform
|
|
60
|
+
var primeRadiant_1 = require("../engine/primeRadiant");
|
|
61
|
+
Object.defineProperty(exports, "createPrimeRadiant", { enumerable: true, get: function () { return primeRadiant_1.createPrimeRadiant; } });
|
|
62
|
+
Object.defineProperty(exports, "PRIME_RADIANT_PRESETS", { enumerable: true, get: function () { return primeRadiant_1.PRIME_RADIANT_PRESETS; } });
|
|
63
|
+
// Science metrics — evaluation metrics for autonomous discovery
|
|
64
|
+
var science_metrics_1 = require("../engine/metrics/science.metrics");
|
|
65
|
+
Object.defineProperty(exports, "SCIENCE_METRICS", { enumerable: true, get: function () { return science_metrics_1.SCIENCE_METRICS; } });
|
|
66
|
+
Object.defineProperty(exports, "SCIENCE_POLICY_TEXT", { enumerable: true, get: function () { return science_metrics_1.SCIENCE_POLICY_TEXT; } });
|
|
67
|
+
Object.defineProperty(exports, "SCIENCE_INITIAL_STATE", { enumerable: true, get: function () { return science_metrics_1.SCIENCE_INITIAL_STATE; } });
|
|
68
|
+
Object.defineProperty(exports, "interpretScienceState", { enumerable: true, get: function () { return science_metrics_1.interpretScienceState; } });
|
|
69
|
+
// ScienceClaw adapter — governance for autonomous scientific discovery
|
|
70
|
+
var scienceclaw_1 = require("../adapters/scienceclaw");
|
|
71
|
+
Object.defineProperty(exports, "createScienceClawAdapter", { enumerable: true, get: function () { return scienceclaw_1.createScienceClawAdapter; } });
|
|
72
|
+
Object.defineProperty(exports, "generateDemoInvestigation", { enumerable: true, get: function () { return scienceclaw_1.generateDemoInvestigation; } });
|
|
73
|
+
// MiroFish adapter — governance wrapper for external simulators
|
|
74
|
+
var mirofish_1 = require("../adapters/mirofish");
|
|
75
|
+
Object.defineProperty(exports, "createMiroFishWrapper", { enumerable: true, get: function () { return mirofish_1.createMiroFishWrapper; } });
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* NeuroVerse Governance Runtime — Types
|
|
4
|
+
*
|
|
5
|
+
* These types define the interface between ANY agent system
|
|
6
|
+
* and the NeuroVerse governance layer.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* import { type AgentAction, type GovernanceVerdict } from "@neuroverseos/runtime"
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neuroverseos/nv-sim",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"description": "CLI for running governed vs baseline agent simulations to explore how world rules shape emergent system behavior.",
|
|
@@ -33,6 +33,9 @@
|
|
|
33
33
|
"test:watch": "vitest",
|
|
34
34
|
"prepublishOnly": "npm run build"
|
|
35
35
|
},
|
|
36
|
+
"optionalDependencies": {
|
|
37
|
+
"@anthropic-ai/sdk": "^0.39.0"
|
|
38
|
+
},
|
|
36
39
|
"dependencies": {
|
|
37
40
|
"@hookform/resolvers": "^3.10.0",
|
|
38
41
|
"@neuroverseos/governance": "^0.3.0",
|
|
@@ -91,7 +94,7 @@
|
|
|
91
94
|
"@tailwindcss/typography": "^0.5.16",
|
|
92
95
|
"@testing-library/jest-dom": "^6.6.0",
|
|
93
96
|
"@testing-library/react": "^16.0.0",
|
|
94
|
-
"@types/node": "^22.
|
|
97
|
+
"@types/node": "^22.19.15",
|
|
95
98
|
"@types/react": "^18.3.23",
|
|
96
99
|
"@types/react-dom": "^18.3.7",
|
|
97
100
|
"@vitejs/plugin-react-swc": "^3.11.0",
|