@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.
Files changed (132) hide show
  1. package/.well-known/ai-plugin.json +34 -9
  2. package/AGENTS.md +72 -24
  3. package/README.md +343 -248
  4. package/dist/adapters/autoresearch.cjs +1345 -0
  5. package/dist/adapters/autoresearch.d.cts +111 -0
  6. package/dist/adapters/autoresearch.d.ts +111 -0
  7. package/dist/adapters/autoresearch.js +12 -0
  8. package/dist/adapters/deep-agents.cjs +1528 -0
  9. package/dist/adapters/deep-agents.d.cts +181 -0
  10. package/dist/adapters/deep-agents.d.ts +181 -0
  11. package/dist/adapters/deep-agents.js +17 -0
  12. package/dist/adapters/express.cjs +1253 -0
  13. package/dist/adapters/express.d.cts +66 -0
  14. package/dist/adapters/express.d.ts +66 -0
  15. package/dist/adapters/express.js +12 -0
  16. package/dist/adapters/index.cjs +2112 -0
  17. package/dist/adapters/index.d.cts +8 -0
  18. package/dist/adapters/index.d.ts +8 -0
  19. package/dist/adapters/index.js +68 -0
  20. package/dist/adapters/langchain.cjs +1315 -0
  21. package/dist/adapters/langchain.d.cts +89 -0
  22. package/dist/adapters/langchain.d.ts +89 -0
  23. package/dist/adapters/langchain.js +17 -0
  24. package/dist/adapters/openai.cjs +1345 -0
  25. package/dist/adapters/openai.d.cts +99 -0
  26. package/dist/adapters/openai.d.ts +99 -0
  27. package/dist/adapters/openai.js +17 -0
  28. package/dist/adapters/openclaw.cjs +1337 -0
  29. package/dist/adapters/openclaw.d.cts +99 -0
  30. package/dist/adapters/openclaw.d.ts +99 -0
  31. package/dist/adapters/openclaw.js +17 -0
  32. package/dist/add-ROOZLU62.js +314 -0
  33. package/dist/behavioral-MJO34S6Q.js +118 -0
  34. package/dist/bootstrap-CQRZVOXK.js +116 -0
  35. package/dist/bootstrap-emitter-Q7UIJZ2O.js +7 -0
  36. package/dist/bootstrap-parser-EEF36XDU.js +7 -0
  37. package/dist/browser.global.js +941 -0
  38. package/dist/build-QKOBBC23.js +341 -0
  39. package/dist/chunk-3WQLXYTP.js +91 -0
  40. package/dist/chunk-4FLICVVA.js +119 -0
  41. package/dist/chunk-4NGDRRQH.js +10 -0
  42. package/dist/chunk-5TPFNWRU.js +215 -0
  43. package/dist/chunk-5U2MQO5P.js +57 -0
  44. package/dist/chunk-6CZSKEY5.js +164 -0
  45. package/dist/chunk-6S5CFQXY.js +624 -0
  46. package/dist/chunk-7P3S7MAY.js +1090 -0
  47. package/dist/chunk-A5W4GNQO.js +130 -0
  48. package/dist/chunk-A7GKPPU7.js +226 -0
  49. package/dist/chunk-AKW5YVCE.js +96 -0
  50. package/dist/chunk-B6OXJLJ5.js +622 -0
  51. package/dist/chunk-BNKJPUPQ.js +113 -0
  52. package/dist/chunk-BQZMOEML.js +43 -0
  53. package/dist/chunk-CNSO6XW5.js +207 -0
  54. package/dist/chunk-CTZHONLA.js +135 -0
  55. package/dist/chunk-D2UCV5AK.js +326 -0
  56. package/dist/chunk-EMQDLDAF.js +458 -0
  57. package/dist/chunk-F66BVUYB.js +340 -0
  58. package/dist/chunk-G7DJ6VOD.js +101 -0
  59. package/dist/chunk-I3RRAYK2.js +11 -0
  60. package/dist/chunk-IS4WUH6Y.js +363 -0
  61. package/dist/chunk-MH7BT4VH.js +15 -0
  62. package/dist/chunk-O5ABKEA7.js +304 -0
  63. package/dist/chunk-OT6PXH54.js +61 -0
  64. package/dist/chunk-PVTQQS3Y.js +186 -0
  65. package/dist/chunk-Q6O7ZLO2.js +62 -0
  66. package/dist/chunk-QLPTHTVB.js +253 -0
  67. package/dist/chunk-QWGCMQQD.js +16 -0
  68. package/dist/chunk-QXBFT7NI.js +201 -0
  69. package/dist/chunk-TG6SEF24.js +246 -0
  70. package/dist/chunk-U6U7EJZL.js +177 -0
  71. package/dist/chunk-W7LLXRGY.js +830 -0
  72. package/dist/chunk-ZJTDUCC2.js +194 -0
  73. package/dist/chunk-ZWI3NIXK.js +314 -0
  74. package/dist/cli/neuroverse.cjs +14191 -0
  75. package/dist/cli/neuroverse.d.cts +1 -0
  76. package/dist/cli/neuroverse.d.ts +1 -0
  77. package/dist/cli/neuroverse.js +227 -0
  78. package/dist/cli/plan.cjs +2439 -0
  79. package/dist/cli/plan.d.cts +20 -0
  80. package/dist/cli/plan.d.ts +20 -0
  81. package/dist/cli/plan.js +353 -0
  82. package/dist/cli/run.cjs +2001 -0
  83. package/dist/cli/run.d.cts +20 -0
  84. package/dist/cli/run.d.ts +20 -0
  85. package/dist/cli/run.js +143 -0
  86. package/dist/configure-ai-6TZ3MCSI.js +132 -0
  87. package/dist/decision-flow-M63D47LO.js +61 -0
  88. package/dist/demo-G43RLCPK.js +469 -0
  89. package/dist/derive-FJZVIPUZ.js +153 -0
  90. package/dist/doctor-6BC6X2VO.js +173 -0
  91. package/dist/equity-penalties-SG5IZQ7I.js +244 -0
  92. package/dist/explain-RHBU2GBR.js +51 -0
  93. package/dist/guard-AJCCGZMF.js +92 -0
  94. package/dist/guard-contract-DqFcTScd.d.cts +821 -0
  95. package/dist/guard-contract-DqFcTScd.d.ts +821 -0
  96. package/dist/guard-engine-PNR6MHCM.js +10 -0
  97. package/dist/impact-3XVDSCBU.js +59 -0
  98. package/dist/improve-TQP4ECSY.js +66 -0
  99. package/dist/index.cjs +7591 -0
  100. package/dist/index.d.cts +2195 -0
  101. package/dist/index.d.ts +2195 -0
  102. package/dist/index.js +472 -0
  103. package/dist/infer-world-IFXCACJ5.js +543 -0
  104. package/dist/init-FYPV4SST.js +144 -0
  105. package/dist/init-world-TI7ARHBT.js +223 -0
  106. package/dist/mcp-server-5Y3ZM7TV.js +13 -0
  107. package/dist/model-adapter-VXEKB4LS.js +11 -0
  108. package/dist/playground-VZBNPPBO.js +560 -0
  109. package/dist/redteam-MZPZD3EF.js +357 -0
  110. package/dist/session-JYOARW54.js +15 -0
  111. package/dist/shared-7RLUHNMU.js +16 -0
  112. package/dist/shared-B8dvUUD8.d.cts +60 -0
  113. package/dist/shared-Dr5Wiay8.d.ts +60 -0
  114. package/dist/simulate-LJXYBC6M.js +83 -0
  115. package/dist/test-BOOR4A5F.js +217 -0
  116. package/dist/trace-PKV4KX56.js +166 -0
  117. package/dist/validate-RALX7CZS.js +81 -0
  118. package/dist/validate-engine-7ZXFVGF2.js +7 -0
  119. package/dist/viz/assets/index-B8SaeJZZ.js +23 -0
  120. package/dist/viz/index.html +23 -0
  121. package/dist/world-BIP4GZBZ.js +376 -0
  122. package/dist/world-loader-Y6HMQH2D.js +13 -0
  123. package/dist/worlds/autoresearch.nv-world.md +230 -0
  124. package/dist/worlds/coding-agent.nv-world.md +211 -0
  125. package/dist/worlds/derivation-world.nv-world.md +278 -0
  126. package/dist/worlds/research-agent.nv-world.md +169 -0
  127. package/dist/worlds/social-media.nv-world.md +198 -0
  128. package/dist/worlds/trading-agent.nv-world.md +218 -0
  129. package/examples/social-media-sim/bridge.py +209 -0
  130. package/examples/social-media-sim/simulation.py +927 -0
  131. package/package.json +16 -3
  132. 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
+ };