@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,113 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GovernanceBlockedError,
|
|
3
|
+
buildEngineOptions,
|
|
4
|
+
extractScope,
|
|
5
|
+
trackPlanProgress
|
|
6
|
+
} from "./chunk-5U2MQO5P.js";
|
|
7
|
+
import {
|
|
8
|
+
evaluateGuard
|
|
9
|
+
} from "./chunk-W7LLXRGY.js";
|
|
10
|
+
import {
|
|
11
|
+
loadWorld
|
|
12
|
+
} from "./chunk-CTZHONLA.js";
|
|
13
|
+
|
|
14
|
+
// src/adapters/openclaw.ts
|
|
15
|
+
var GovernanceBlockedError2 = class extends GovernanceBlockedError {
|
|
16
|
+
action;
|
|
17
|
+
constructor(verdict, action) {
|
|
18
|
+
super(verdict);
|
|
19
|
+
this.action = action;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
function defaultMapAction(action, direction) {
|
|
23
|
+
return {
|
|
24
|
+
intent: action.type,
|
|
25
|
+
tool: action.tool ?? action.type,
|
|
26
|
+
args: action.input,
|
|
27
|
+
direction,
|
|
28
|
+
scope: action.input ? extractScope(action.input) : void 0
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
var NeuroVersePlugin = class {
|
|
32
|
+
name = "neuroverse-governance";
|
|
33
|
+
world;
|
|
34
|
+
options;
|
|
35
|
+
engineOptions;
|
|
36
|
+
mapAction;
|
|
37
|
+
activePlan;
|
|
38
|
+
constructor(world, options = {}) {
|
|
39
|
+
this.world = world;
|
|
40
|
+
this.options = options;
|
|
41
|
+
this.activePlan = options.plan;
|
|
42
|
+
this.engineOptions = buildEngineOptions(options, this.activePlan);
|
|
43
|
+
this.mapAction = options.mapAction ?? defaultMapAction;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Evaluate an action before execution.
|
|
47
|
+
*
|
|
48
|
+
* @throws GovernanceBlockedError if BLOCKED
|
|
49
|
+
* @returns HookResult with verdict details
|
|
50
|
+
*/
|
|
51
|
+
beforeAction(action) {
|
|
52
|
+
const event = this.mapAction(action, "input");
|
|
53
|
+
this.engineOptions.plan = this.activePlan;
|
|
54
|
+
const verdict = evaluateGuard(event, this.world, this.engineOptions);
|
|
55
|
+
const result = {
|
|
56
|
+
allowed: verdict.status === "ALLOW",
|
|
57
|
+
verdict,
|
|
58
|
+
action
|
|
59
|
+
};
|
|
60
|
+
this.options.onEvaluate?.(result);
|
|
61
|
+
if (verdict.status === "BLOCK") {
|
|
62
|
+
throw new GovernanceBlockedError2(verdict, action);
|
|
63
|
+
}
|
|
64
|
+
if (verdict.status === "ALLOW") {
|
|
65
|
+
trackPlanProgress(event, this, this.options);
|
|
66
|
+
}
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Evaluate an action's output (post-execution governance).
|
|
71
|
+
* Only runs if evaluateOutputs is enabled.
|
|
72
|
+
*
|
|
73
|
+
* @returns HookResult or null if output evaluation is disabled
|
|
74
|
+
*/
|
|
75
|
+
afterAction(action, _output) {
|
|
76
|
+
if (!this.options.evaluateOutputs) return null;
|
|
77
|
+
const event = this.mapAction(action, "output");
|
|
78
|
+
const verdict = evaluateGuard(event, this.world, this.engineOptions);
|
|
79
|
+
const result = {
|
|
80
|
+
allowed: verdict.status === "ALLOW",
|
|
81
|
+
verdict,
|
|
82
|
+
action
|
|
83
|
+
};
|
|
84
|
+
this.options.onEvaluate?.(result);
|
|
85
|
+
if (verdict.status === "BLOCK") {
|
|
86
|
+
throw new GovernanceBlockedError2(verdict, action);
|
|
87
|
+
}
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Get the plugin hooks object for agent.use().
|
|
92
|
+
*/
|
|
93
|
+
hooks() {
|
|
94
|
+
return {
|
|
95
|
+
beforeAction: (action) => this.beforeAction(action),
|
|
96
|
+
afterAction: (action, output) => this.afterAction(action, output)
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
async function createNeuroVersePlugin(worldPath, options) {
|
|
101
|
+
const world = await loadWorld(worldPath);
|
|
102
|
+
return new NeuroVersePlugin(world, options);
|
|
103
|
+
}
|
|
104
|
+
function createNeuroVersePluginFromWorld(world, options) {
|
|
105
|
+
return new NeuroVersePlugin(world, options);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export {
|
|
109
|
+
GovernanceBlockedError2 as GovernanceBlockedError,
|
|
110
|
+
NeuroVersePlugin,
|
|
111
|
+
createNeuroVersePlugin,
|
|
112
|
+
createNeuroVersePluginFromWorld
|
|
113
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// src/cli/cli-utils.ts
|
|
2
|
+
async function resolveWorldPath(input) {
|
|
3
|
+
const { stat } = await import("fs/promises");
|
|
4
|
+
try {
|
|
5
|
+
const info = await stat(input);
|
|
6
|
+
if (info.isDirectory()) return input;
|
|
7
|
+
} catch {
|
|
8
|
+
}
|
|
9
|
+
const neuroversePath = `.neuroverse/worlds/${input}`;
|
|
10
|
+
try {
|
|
11
|
+
const info = await stat(neuroversePath);
|
|
12
|
+
if (info.isDirectory()) return neuroversePath;
|
|
13
|
+
} catch {
|
|
14
|
+
}
|
|
15
|
+
throw new Error(
|
|
16
|
+
`World not found: "${input}"
|
|
17
|
+
Tried:
|
|
18
|
+
${input}
|
|
19
|
+
${neuroversePath}
|
|
20
|
+
|
|
21
|
+
Build a world first: neuroverse build <input.md>`
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
async function readStdin() {
|
|
25
|
+
const chunks = [];
|
|
26
|
+
for await (const chunk of process.stdin) {
|
|
27
|
+
chunks.push(chunk);
|
|
28
|
+
}
|
|
29
|
+
return Buffer.concat(chunks).toString("utf-8");
|
|
30
|
+
}
|
|
31
|
+
function parseCliValue(raw) {
|
|
32
|
+
if (raw === "true") return true;
|
|
33
|
+
if (raw === "false") return false;
|
|
34
|
+
const num = Number(raw);
|
|
35
|
+
if (!isNaN(num) && raw.trim() !== "") return num;
|
|
36
|
+
return raw;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export {
|
|
40
|
+
resolveWorldPath,
|
|
41
|
+
readStdin,
|
|
42
|
+
parseCliValue
|
|
43
|
+
};
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
// src/engine/behavioral-engine.ts
|
|
2
|
+
var ACTION_CATEGORY_MAP = {
|
|
3
|
+
// Amplifying
|
|
4
|
+
share: "amplifying",
|
|
5
|
+
post: "amplifying",
|
|
6
|
+
create_post: "amplifying",
|
|
7
|
+
retweet: "amplifying",
|
|
8
|
+
quote_tweet: "amplifying",
|
|
9
|
+
broadcast: "amplifying",
|
|
10
|
+
publish: "amplifying",
|
|
11
|
+
// Passive
|
|
12
|
+
scroll: "passive",
|
|
13
|
+
idle: "passive",
|
|
14
|
+
observe: "passive",
|
|
15
|
+
like: "passive",
|
|
16
|
+
// Engaging
|
|
17
|
+
reply: "engaging",
|
|
18
|
+
comment: "engaging",
|
|
19
|
+
discuss: "engaging",
|
|
20
|
+
// Corrective
|
|
21
|
+
report: "corrective",
|
|
22
|
+
fact_check: "corrective",
|
|
23
|
+
flag: "corrective",
|
|
24
|
+
debunk: "corrective",
|
|
25
|
+
// Transactional
|
|
26
|
+
buy: "transactional",
|
|
27
|
+
sell: "transactional",
|
|
28
|
+
trade: "transactional",
|
|
29
|
+
short: "transactional",
|
|
30
|
+
// Creative
|
|
31
|
+
generate: "creative",
|
|
32
|
+
compose: "creative",
|
|
33
|
+
draft: "creative",
|
|
34
|
+
write: "creative",
|
|
35
|
+
// Analytical
|
|
36
|
+
analyze: "analytical",
|
|
37
|
+
research: "analytical",
|
|
38
|
+
investigate: "analytical",
|
|
39
|
+
review: "analytical"
|
|
40
|
+
};
|
|
41
|
+
var SHIFT_LABELS = {
|
|
42
|
+
"amplifying\u2192passive": "amplification_suppressed",
|
|
43
|
+
"amplifying\u2192corrective": "redirected_to_reporting",
|
|
44
|
+
"amplifying\u2192engaging": "shifted_to_engagement",
|
|
45
|
+
"amplifying\u2192analytical": "redirected_to_analysis",
|
|
46
|
+
"transactional\u2192passive": "trading_halted",
|
|
47
|
+
"transactional\u2192analytical": "redirected_to_analysis",
|
|
48
|
+
"creative\u2192passive": "creation_blocked",
|
|
49
|
+
"creative\u2192analytical": "redirected_to_research",
|
|
50
|
+
"engaging\u2192passive": "engagement_dampened",
|
|
51
|
+
"passive\u2192passive": "unchanged"
|
|
52
|
+
};
|
|
53
|
+
function categorizeAction(action) {
|
|
54
|
+
return ACTION_CATEGORY_MAP[action] ?? "unknown";
|
|
55
|
+
}
|
|
56
|
+
function classifyAdaptation(intendedAction, executedAction) {
|
|
57
|
+
if (intendedAction === executedAction) return "unchanged";
|
|
58
|
+
const intendedCat = categorizeAction(intendedAction);
|
|
59
|
+
const executedCat = categorizeAction(executedAction);
|
|
60
|
+
if (intendedCat === executedCat) return "unchanged";
|
|
61
|
+
const key = `${intendedCat}\u2192${executedCat}`;
|
|
62
|
+
return SHIFT_LABELS[key] ?? `${intendedAction}_to_${executedAction}`;
|
|
63
|
+
}
|
|
64
|
+
function adaptationFromVerdict(agentId, intendedAction, executedAction, verdict) {
|
|
65
|
+
return {
|
|
66
|
+
agentId,
|
|
67
|
+
intendedAction,
|
|
68
|
+
executedAction,
|
|
69
|
+
shiftType: classifyAdaptation(intendedAction, executedAction),
|
|
70
|
+
verdict: verdict.status,
|
|
71
|
+
ruleId: verdict.ruleId,
|
|
72
|
+
reason: verdict.reason
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function detectBehavioralPatterns(adaptations, totalAgents) {
|
|
76
|
+
const patterns = [];
|
|
77
|
+
if (adaptations.length === 0) return patterns;
|
|
78
|
+
const n = Math.max(totalAgents, 1);
|
|
79
|
+
const shiftCounts = {};
|
|
80
|
+
for (const a of adaptations) {
|
|
81
|
+
shiftCounts[a.shiftType] = (shiftCounts[a.shiftType] ?? 0) + 1;
|
|
82
|
+
}
|
|
83
|
+
const verdictCounts = {};
|
|
84
|
+
for (const a of adaptations) {
|
|
85
|
+
verdictCounts[a.verdict] = (verdictCounts[a.verdict] ?? 0) + 1;
|
|
86
|
+
}
|
|
87
|
+
const suppressed = shiftCounts["amplification_suppressed"] ?? 0;
|
|
88
|
+
const dampened = shiftCounts["engagement_dampened"] ?? 0;
|
|
89
|
+
const silenced = suppressed + dampened;
|
|
90
|
+
if (silenced >= 3) {
|
|
91
|
+
patterns.push({
|
|
92
|
+
type: "coordinated_silence",
|
|
93
|
+
description: `${silenced} agents blocked from amplifying \u2014 network went quiet`,
|
|
94
|
+
strength: round(silenced / n),
|
|
95
|
+
agentsAffected: silenced
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
if (suppressed >= 2) {
|
|
99
|
+
patterns.push({
|
|
100
|
+
type: "misinfo_suppression",
|
|
101
|
+
description: `${suppressed} amplification attempts blocked before reaching the feed`,
|
|
102
|
+
strength: round(suppressed / n),
|
|
103
|
+
agentsAffected: suppressed
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
const redirected = (shiftCounts["redirected_to_reporting"] ?? 0) + (shiftCounts["redirected_to_analysis"] ?? 0);
|
|
107
|
+
if (redirected >= 1) {
|
|
108
|
+
patterns.push({
|
|
109
|
+
type: "constructive_redirect",
|
|
110
|
+
description: `${redirected} agents redirected from amplification to reporting or analysis`,
|
|
111
|
+
strength: round(redirected / n),
|
|
112
|
+
agentsAffected: redirected
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
const tradingHalted = shiftCounts["trading_halted"] ?? 0;
|
|
116
|
+
if (tradingHalted >= 2) {
|
|
117
|
+
patterns.push({
|
|
118
|
+
type: "trading_halt",
|
|
119
|
+
description: `${tradingHalted} trading agents stopped \u2014 positions frozen`,
|
|
120
|
+
strength: round(tradingHalted / n),
|
|
121
|
+
agentsAffected: tradingHalted
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
const adaptRate = adaptations.length / n;
|
|
125
|
+
if (adaptRate > 0.3) {
|
|
126
|
+
patterns.push({
|
|
127
|
+
type: "high_governance_impact",
|
|
128
|
+
description: `${adaptations.length}/${n} agents (${Math.round(adaptRate * 100)}%) had their behavior shaped by governance`,
|
|
129
|
+
strength: round(adaptRate),
|
|
130
|
+
agentsAffected: adaptations.length
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
const penalized = verdictCounts["PENALIZE"] ?? 0;
|
|
134
|
+
if (penalized >= 3) {
|
|
135
|
+
patterns.push({
|
|
136
|
+
type: "penalty_wave",
|
|
137
|
+
description: `${penalized} agents penalized \u2014 behavioral costs applied`,
|
|
138
|
+
strength: round(penalized / n),
|
|
139
|
+
agentsAffected: penalized
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
const rewarded = verdictCounts["REWARD"] ?? 0;
|
|
143
|
+
if (rewarded >= 3) {
|
|
144
|
+
patterns.push({
|
|
145
|
+
type: "reward_cascade",
|
|
146
|
+
description: `${rewarded} agents rewarded \u2014 constructive behavior amplified`,
|
|
147
|
+
strength: round(rewarded / n),
|
|
148
|
+
agentsAffected: rewarded
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
return patterns;
|
|
152
|
+
}
|
|
153
|
+
function generateAdaptationNarrative(patterns, context) {
|
|
154
|
+
if (patterns.length === 0) return "";
|
|
155
|
+
const parts = [];
|
|
156
|
+
const patternTypes = new Set(patterns.map((p) => p.type));
|
|
157
|
+
if (patternTypes.has("misinfo_suppression")) {
|
|
158
|
+
const p = patterns.find((p2) => p2.type === "misinfo_suppression");
|
|
159
|
+
parts.push(`Blocked ${p.agentsAffected} misinformation amplification attempts`);
|
|
160
|
+
}
|
|
161
|
+
if (patternTypes.has("coordinated_silence")) {
|
|
162
|
+
const p = patterns.find((p2) => p2.type === "coordinated_silence");
|
|
163
|
+
parts.push(`${p.agentsAffected} agents went silent instead of amplifying`);
|
|
164
|
+
}
|
|
165
|
+
if (patternTypes.has("constructive_redirect")) {
|
|
166
|
+
const p = patterns.find((p2) => p2.type === "constructive_redirect");
|
|
167
|
+
parts.push(`${p.agentsAffected} shifted from sharing to fact-checking`);
|
|
168
|
+
}
|
|
169
|
+
if (patternTypes.has("trading_halt")) {
|
|
170
|
+
const p = patterns.find((p2) => p2.type === "trading_halt");
|
|
171
|
+
parts.push(`${p.agentsAffected} trading agents halted`);
|
|
172
|
+
}
|
|
173
|
+
if (patternTypes.has("penalty_wave")) {
|
|
174
|
+
const p = patterns.find((p2) => p2.type === "penalty_wave");
|
|
175
|
+
parts.push(`${p.agentsAffected} agents received behavioral penalties`);
|
|
176
|
+
}
|
|
177
|
+
if (patternTypes.has("reward_cascade")) {
|
|
178
|
+
const p = patterns.find((p2) => p2.type === "reward_cascade");
|
|
179
|
+
parts.push(`${p.agentsAffected} agents rewarded for constructive behavior`);
|
|
180
|
+
}
|
|
181
|
+
if (patternTypes.has("high_governance_impact")) {
|
|
182
|
+
const p = patterns.find((p2) => p2.type === "high_governance_impact");
|
|
183
|
+
parts.push(`${Math.round(p.strength * 100)}% of agents had behavior shaped by governance`);
|
|
184
|
+
}
|
|
185
|
+
if (context) {
|
|
186
|
+
const contextParts = [];
|
|
187
|
+
if (context.mood) contextParts.push(`mood: ${context.mood}`);
|
|
188
|
+
if (context.misinfoLevel !== void 0) {
|
|
189
|
+
contextParts.push(`misinfo level: ${Math.round(context.misinfoLevel * 100)}%`);
|
|
190
|
+
}
|
|
191
|
+
if (contextParts.length > 0) {
|
|
192
|
+
parts.push(`Network ${contextParts.join(", ")}`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return parts.join(". ") + (parts.length > 0 ? "." : "");
|
|
196
|
+
}
|
|
197
|
+
function round(n, decimals = 3) {
|
|
198
|
+
const factor = Math.pow(10, decimals);
|
|
199
|
+
return Math.round(n * factor) / factor;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export {
|
|
203
|
+
classifyAdaptation,
|
|
204
|
+
adaptationFromVerdict,
|
|
205
|
+
detectBehavioralPatterns,
|
|
206
|
+
generateAdaptationNarrative
|
|
207
|
+
};
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
// src/loader/world-loader.ts
|
|
2
|
+
async function loadWorldFromDirectory(dirPath) {
|
|
3
|
+
const { readFile } = await import("fs/promises");
|
|
4
|
+
const { join } = await import("path");
|
|
5
|
+
const { readdirSync } = await import("fs");
|
|
6
|
+
async function readJson(filename) {
|
|
7
|
+
const filePath = join(dirPath, filename);
|
|
8
|
+
try {
|
|
9
|
+
const content = await readFile(filePath, "utf-8");
|
|
10
|
+
return JSON.parse(content);
|
|
11
|
+
} catch (err) {
|
|
12
|
+
if (err instanceof Error && "code" in err && err.code === "ENOENT") {
|
|
13
|
+
return void 0;
|
|
14
|
+
}
|
|
15
|
+
process.stderr.write(
|
|
16
|
+
`[neuroverse] Warning: Failed to read ${filename}: ${err instanceof Error ? err.message : String(err)}
|
|
17
|
+
`
|
|
18
|
+
);
|
|
19
|
+
return void 0;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const worldJson = await readJson("world.json");
|
|
23
|
+
if (!worldJson) {
|
|
24
|
+
throw new Error(`Cannot read world.json in ${dirPath}`);
|
|
25
|
+
}
|
|
26
|
+
const invariantsJson = await readJson("invariants.json");
|
|
27
|
+
const assumptionsJson = await readJson("assumptions.json");
|
|
28
|
+
const stateSchemaJson = await readJson("state-schema.json");
|
|
29
|
+
const gatesJson = await readJson("gates.json");
|
|
30
|
+
const outcomesJson = await readJson("outcomes.json");
|
|
31
|
+
const guardsJson = await readJson("guards.json");
|
|
32
|
+
const rolesJson = await readJson("roles.json");
|
|
33
|
+
const kernelJson = await readJson("kernel.json");
|
|
34
|
+
const metadataJson = await readJson("metadata.json");
|
|
35
|
+
const rules = [];
|
|
36
|
+
try {
|
|
37
|
+
const rulesDir = join(dirPath, "rules");
|
|
38
|
+
const ruleFiles = readdirSync(rulesDir).filter((f) => f.endsWith(".json")).sort();
|
|
39
|
+
for (const file of ruleFiles) {
|
|
40
|
+
try {
|
|
41
|
+
const content = await readFile(join(rulesDir, file), "utf-8");
|
|
42
|
+
rules.push(JSON.parse(content));
|
|
43
|
+
} catch (err) {
|
|
44
|
+
process.stderr.write(
|
|
45
|
+
`[neuroverse] Warning: Failed to parse rule ${file}: ${err instanceof Error ? err.message : String(err)}
|
|
46
|
+
`
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
} catch (err) {
|
|
51
|
+
if (!(err instanceof Error && "code" in err && err.code === "ENOENT")) {
|
|
52
|
+
process.stderr.write(
|
|
53
|
+
`[neuroverse] Warning: Failed to read rules directory: ${err instanceof Error ? err.message : String(err)}
|
|
54
|
+
`
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
world: worldJson,
|
|
60
|
+
invariants: invariantsJson?.invariants ?? [],
|
|
61
|
+
assumptions: assumptionsJson ?? { profiles: {}, parameter_definitions: {} },
|
|
62
|
+
stateSchema: stateSchemaJson ?? { variables: {}, presets: {} },
|
|
63
|
+
rules,
|
|
64
|
+
gates: gatesJson ?? {
|
|
65
|
+
viability_classification: [],
|
|
66
|
+
structural_override: { description: "", enforcement: "mandatory" },
|
|
67
|
+
sustainability_threshold: 0,
|
|
68
|
+
collapse_visual: { background: "", text: "", border: "", label: "" }
|
|
69
|
+
},
|
|
70
|
+
outcomes: outcomesJson ?? {
|
|
71
|
+
computed_outcomes: [],
|
|
72
|
+
comparison_layout: { primary_card: "", status_badge: "", structural_indicators: [] }
|
|
73
|
+
},
|
|
74
|
+
guards: guardsJson,
|
|
75
|
+
roles: rolesJson,
|
|
76
|
+
kernel: kernelJson,
|
|
77
|
+
metadata: metadataJson ?? {
|
|
78
|
+
format_version: "1.0.0",
|
|
79
|
+
created_at: "",
|
|
80
|
+
last_modified: "",
|
|
81
|
+
authoring_method: "manual-authoring"
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
async function loadWorld(worldPath) {
|
|
86
|
+
const { stat } = await import("fs/promises");
|
|
87
|
+
const info = await stat(worldPath);
|
|
88
|
+
if (info.isDirectory()) {
|
|
89
|
+
return loadWorldFromDirectory(worldPath);
|
|
90
|
+
}
|
|
91
|
+
throw new Error(`Cannot load world from: ${worldPath} \u2014 expected a directory`);
|
|
92
|
+
}
|
|
93
|
+
var DEFAULT_BUNDLED_WORLD = "coding-agent";
|
|
94
|
+
async function loadBundledWorld(name = DEFAULT_BUNDLED_WORLD) {
|
|
95
|
+
const { readFile } = await import("fs/promises");
|
|
96
|
+
const { join, dirname } = await import("path");
|
|
97
|
+
const { existsSync } = await import("fs");
|
|
98
|
+
const { fileURLToPath } = await import("url");
|
|
99
|
+
const { parseWorldMarkdown } = await import("./bootstrap-parser-EEF36XDU.js");
|
|
100
|
+
const { emitWorldDefinition } = await import("./bootstrap-emitter-Q7UIJZ2O.js");
|
|
101
|
+
const filename = `${name}.nv-world.md`;
|
|
102
|
+
let packageRoot;
|
|
103
|
+
try {
|
|
104
|
+
const thisFile = typeof __dirname !== "undefined" ? __dirname : dirname(fileURLToPath(import.meta.url));
|
|
105
|
+
packageRoot = join(thisFile, "..", "..");
|
|
106
|
+
} catch {
|
|
107
|
+
packageRoot = process.cwd();
|
|
108
|
+
}
|
|
109
|
+
const candidates = [
|
|
110
|
+
join(packageRoot, "dist", "worlds", filename),
|
|
111
|
+
join(packageRoot, "src", "worlds", filename)
|
|
112
|
+
];
|
|
113
|
+
for (const candidate of candidates) {
|
|
114
|
+
if (existsSync(candidate)) {
|
|
115
|
+
const markdown = await readFile(candidate, "utf-8");
|
|
116
|
+
const parsed = parseWorldMarkdown(markdown);
|
|
117
|
+
if (!parsed.world) {
|
|
118
|
+
throw new Error(`Failed to parse bundled world: ${candidate}`);
|
|
119
|
+
}
|
|
120
|
+
const { world } = emitWorldDefinition(parsed.world);
|
|
121
|
+
return world;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
throw new Error(
|
|
125
|
+
`Bundled world "${name}" not found. Searched:
|
|
126
|
+
` + candidates.map((c) => ` ${c}`).join("\n")
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export {
|
|
131
|
+
loadWorldFromDirectory,
|
|
132
|
+
loadWorld,
|
|
133
|
+
DEFAULT_BUNDLED_WORLD,
|
|
134
|
+
loadBundledWorld
|
|
135
|
+
};
|